| // Copyright 2021 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package a |
| |
| // SliceEqual reports whether two slices are equal: the same length and all |
| // elements equal. All floating point NaNs are considered equal. |
| func SliceEqual[Elem comparable](s1, s2 []Elem) bool { |
| if len(s1) != len(s2) { |
| return false |
| } |
| for i, v1 := range s1 { |
| v2 := s2[i] |
| if v1 != v2 { |
| isNaN := func(f Elem) bool { return f != f } |
| if !isNaN(v1) || !isNaN(v2) { |
| return false |
| } |
| } |
| } |
| return true |
| } |
| |
| // A Set is a set of elements of some type. |
| type Set[Elem comparable] struct { |
| m map[Elem]struct{} |
| } |
| |
| // Make makes a new set. |
| func Make[Elem comparable]() Set[Elem] { |
| return Set[Elem]{m: make(map[Elem]struct{})} |
| } |
| |
| // Add adds an element to a set. |
| func (s Set[Elem]) Add(v Elem) { |
| s.m[v] = struct{}{} |
| } |
| |
| // Delete removes an element from a set. If the element is not present |
| // in the set, this does nothing. |
| func (s Set[Elem]) Delete(v Elem) { |
| delete(s.m, v) |
| } |
| |
| // Contains reports whether v is in the set. |
| func (s Set[Elem]) Contains(v Elem) bool { |
| _, ok := s.m[v] |
| return ok |
| } |
| |
| // Len returns the number of elements in the set. |
| func (s Set[Elem]) Len() int { |
| return len(s.m) |
| } |
| |
| // Values returns the values in the set. |
| // The values will be in an indeterminate order. |
| func (s Set[Elem]) Values() []Elem { |
| r := make([]Elem, 0, len(s.m)) |
| for v := range s.m { |
| r = append(r, v) |
| } |
| return r |
| } |
| |
| // Equal reports whether two sets contain the same elements. |
| func Equal[Elem comparable](s1, s2 Set[Elem]) bool { |
| if len(s1.m) != len(s2.m) { |
| return false |
| } |
| for v1 := range s1.m { |
| if !s2.Contains(v1) { |
| return false |
| } |
| } |
| return true |
| } |
| |
| // Copy returns a copy of s. |
| func (s Set[Elem]) Copy() Set[Elem] { |
| r := Set[Elem]{m: make(map[Elem]struct{}, len(s.m))} |
| for v := range s.m { |
| r.m[v] = struct{}{} |
| } |
| return r |
| } |
| |
| // AddSet adds all the elements of s2 to s. |
| func (s Set[Elem]) AddSet(s2 Set[Elem]) { |
| for v := range s2.m { |
| s.m[v] = struct{}{} |
| } |
| } |
| |
| // SubSet removes all elements in s2 from s. |
| // Values in s2 that are not in s are ignored. |
| func (s Set[Elem]) SubSet(s2 Set[Elem]) { |
| for v := range s2.m { |
| delete(s.m, v) |
| } |
| } |
| |
| // Intersect removes all elements from s that are not present in s2. |
| // Values in s2 that are not in s are ignored. |
| func (s Set[Elem]) Intersect(s2 Set[Elem]) { |
| for v := range s.m { |
| if !s2.Contains(v) { |
| delete(s.m, v) |
| } |
| } |
| } |
| |
| // Iterate calls f on every element in the set. |
| func (s Set[Elem]) Iterate(f func(Elem)) { |
| for v := range s.m { |
| f(v) |
| } |
| } |
| |
| // Filter deletes any elements from s for which f returns false. |
| func (s Set[Elem]) Filter(f func(Elem) bool) { |
| for v := range s.m { |
| if !f(v) { |
| delete(s.m, v) |
| } |
| } |
| } |