mirror of https://github.com/go-gitea/gitea
Add container.FilterSlice function (#30339)
Many places have the following logic: ```go func (jobs ActionJobList) GetRunIDs() []int64 { ids := make(container.Set[int64], len(jobs)) for _, j := range jobs { if j.RunID == 0 { continue } ids.Add(j.RunID) } return ids.Values() } ``` this introduces a `container.FilterMapUnique` function, which reduces the code above to: ```go func (jobs ActionJobList) GetRunIDs() []int64 { return container.FilterMapUnique(jobs, func(j *ActionRunJob) (int64, bool) { return j.RunID, j.RunID != 0 }) } ```pull/30360/head^2
parent
8d14266269
commit
d547b53cca
@ -0,0 +1,21 @@ |
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package container |
||||
|
||||
import "slices" |
||||
|
||||
// FilterSlice ranges over the slice and calls include() for each element.
|
||||
// If the second returned value is true, the first returned value will be included in the resulting
|
||||
// slice (after deduplication).
|
||||
func FilterSlice[E any, T comparable](s []E, include func(E) (T, bool)) []T { |
||||
filtered := make([]T, 0, len(s)) // slice will be clipped before returning
|
||||
seen := make(map[T]bool, len(s)) |
||||
for i := range s { |
||||
if v, ok := include(s[i]); ok && !seen[v] { |
||||
filtered = append(filtered, v) |
||||
seen[v] = true |
||||
} |
||||
} |
||||
return slices.Clip(filtered) |
||||
} |
@ -0,0 +1,28 @@ |
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package container |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/stretchr/testify/assert" |
||||
) |
||||
|
||||
func TestFilterMapUnique(t *testing.T) { |
||||
result := FilterSlice([]int{ |
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
||||
}, func(i int) (int, bool) { |
||||
switch i { |
||||
case 0: |
||||
return 0, true // included later
|
||||
case 1: |
||||
return 0, true // duplicate of previous (should be ignored)
|
||||
case 2: |
||||
return 2, false // not included
|
||||
default: |
||||
return i, true |
||||
} |
||||
}) |
||||
assert.Equal(t, []int{0, 3, 4, 5, 6, 7, 8, 9}, result) |
||||
} |
Loading…
Reference in new issue