mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 13:05:46 +00:00
types/views: add SliceEqualAnyOrder func
This is based on the tagsEqual func from corp/control/control.go, moved here so that it can be reused in other places. Signed-off-by: Will Norris <will@tailscale.com>
This commit is contained in:
parent
1e67947cfa
commit
3becf82dd3
@ -170,6 +170,37 @@ func SliceContains[T comparable](v Slice[T], e T) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SliceEqualAnyOrder reports whether a and b contain the same elements, regardless of order.
|
||||||
|
// The underlying slices for a and b can be nil.
|
||||||
|
func SliceEqualAnyOrder[T comparable](a, b Slice[T]) bool {
|
||||||
|
if a.Len() != b.Len() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var diffStart int // beginning index where a and b differ
|
||||||
|
for n := a.Len(); diffStart < n; diffStart++ {
|
||||||
|
if a.At(diffStart) != b.At(diffStart) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if diffStart == a.Len() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// count the occurrences of remaining values and compare
|
||||||
|
valueCount := make(map[T]int)
|
||||||
|
for i, n := diffStart, a.Len(); i < n; i++ {
|
||||||
|
valueCount[a.At(i)]++
|
||||||
|
valueCount[b.At(i)]--
|
||||||
|
}
|
||||||
|
for _, count := range valueCount {
|
||||||
|
if count != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// IPPrefixSlice is a read-only accessor for a slice of netip.Prefix.
|
// IPPrefixSlice is a read-only accessor for a slice of netip.Prefix.
|
||||||
type IPPrefixSlice struct {
|
type IPPrefixSlice struct {
|
||||||
ж Slice[netip.Prefix]
|
ж Slice[netip.Prefix]
|
||||||
|
@ -125,4 +125,8 @@ func TestViewUtils(t *testing.T) {
|
|||||||
c.Check(v.IndexFunc(func(s string) bool { return strings.HasPrefix(s, "z") }), 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, "bar"), qt.Equals, true)
|
||||||
c.Check(SliceContains(v, "baz"), qt.Equals, false)
|
c.Check(SliceContains(v, "baz"), qt.Equals, false)
|
||||||
|
c.Check(SliceEqualAnyOrder(v, v), qt.Equals, true)
|
||||||
|
c.Check(SliceEqualAnyOrder(v, SliceOf([]string{"bar", "foo"})), qt.Equals, true)
|
||||||
|
c.Check(SliceEqualAnyOrder(v, SliceOf([]string{"foo"})), qt.Equals, false)
|
||||||
|
c.Check(SliceEqualAnyOrder(SliceOf([]string{"a", "a", "b"}), SliceOf([]string{"a", "b", "b"})), qt.Equals, false)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user