types/views: add SliceContains, View.ContainsFunc, View.IndexFunc

We were starting to write these elsewhere as little unexported copies
in misc places.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2022-07-21 08:06:01 -07:00 committed by Brad Fitzpatrick
parent d8cb5aae17
commit 43f3a969ca
2 changed files with 50 additions and 0 deletions

View File

@ -132,6 +132,43 @@ func (v Slice[T]) AsSlice() []T {
return v.AppendTo(v.ж[:0:0])
}
// IndexFunc returns the first index of an element in v satisfying f(e),
// or -1 if none do.
//
// As it runs in O(n) time, use with care.
func (v Slice[T]) IndexFunc(f func(T) bool) int {
for i := 0; i < v.Len(); i++ {
if f(v.At(i)) {
return i
}
}
return -1
}
// ContainsFunc reports whether any element in v satisfies f(e).
//
// As it runs in O(n) time, use with care.
func (v Slice[T]) ContainsFunc(f func(T) bool) bool {
for i := 0; i < v.Len(); i++ {
if f(v.At(i)) {
return true
}
}
return false
}
// SliceContains reports whether v contains element e.
//
// As it runs in O(n) time, use with care.
func SliceContains[T comparable](v Slice[T], e T) bool {
for i := 0; i < v.Len(); i++ {
if v.At(i) == e {
return true
}
}
return false
}
// IPPrefixSlice is a read-only accessor for a slice of netaddr.IPPrefix.
type IPPrefixSlice struct {
ж Slice[netaddr.IPPrefix]

View File

@ -11,6 +11,7 @@
"strings"
"testing"
qt "github.com/frankban/quicktest"
"inet.af/netaddr"
)
@ -73,3 +74,15 @@ type viewStruct struct {
}
}
}
func TestViewUtils(t *testing.T) {
v := SliceOf([]string{"foo", "bar"})
c := qt.New(t)
c.Check(v.ContainsFunc(func(s string) bool { return strings.HasPrefix(s, "f") }), qt.Equals, true)
c.Check(v.ContainsFunc(func(s string) bool { return strings.HasPrefix(s, "g") }), qt.Equals, false)
c.Check(v.IndexFunc(func(s string) bool { return strings.HasPrefix(s, "b") }), qt.Equals, 1)
c.Check(v.IndexFunc(func(s string) bool { return strings.HasPrefix(s, "z") }), qt.Equals, -1)
c.Check(SliceContains(v, "bar"), qt.Equals, true)
c.Check(SliceContains(v, "baz"), qt.Equals, false)
}