diff --git a/util/slicesx/slicesx.go b/util/slicesx/slicesx.go index d72722ce0..6896c1f3c 100644 --- a/util/slicesx/slicesx.go +++ b/util/slicesx/slicesx.go @@ -91,3 +91,13 @@ func Filter[S ~[]T, T any](dst, src S, fn func(T) bool) S { } return dst } + +// AppendMatching appends elements in ps to dst if f(x) is true. +func AppendMatching[T any](dst, ps []T, f func(T) bool) []T { + for _, p := range ps { + if f(p) { + dst = append(dst, p) + } + } + return dst +} diff --git a/util/slicesx/slicesx_test.go b/util/slicesx/slicesx_test.go index 46bd666c3..854fe824d 100644 --- a/util/slicesx/slicesx_test.go +++ b/util/slicesx/slicesx_test.go @@ -136,3 +136,18 @@ func TestFilterNoAllocations(t *testing.T) { t.Fatalf("got %.4f allocs, want 1", allocs) } } + +func TestAppendMatching(t *testing.T) { + v := []string{"one", "two", "three", "four"} + got := AppendMatching(v[:0], v, func(s string) bool { return len(s) > 3 }) + + want := []string{"three", "four"} + if !reflect.DeepEqual(got, want) { + t.Errorf("got %v; want %v", got, want) + } + + wantOrigMem := []string{"three", "four", "three", "four"} + if !reflect.DeepEqual(v, wantOrigMem) { + t.Errorf("got %v; want %v", v, wantOrigMem) + } +}