mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-07-12 14:12:27 +02:00
fn: add new generic set container
This commit is contained in:
95
fn/set.go
Normal file
95
fn/set.go
Normal file
@ -0,0 +1,95 @@
|
||||
package fn
|
||||
|
||||
import "golang.org/x/exp/maps"
|
||||
|
||||
// Set is a generic set using type params that supports the following
|
||||
// operations: diff, union, intersection, and subset.
|
||||
type Set[T comparable] map[T]struct{}
|
||||
|
||||
// NewSet returns a new set with the given elements.
|
||||
func NewSet[T comparable](elems ...T) Set[T] {
|
||||
s := make(Set[T])
|
||||
for _, e := range elems {
|
||||
s.Add(e)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Add adds an element to the set.
|
||||
func (s Set[T]) Add(e T) {
|
||||
s[e] = struct{}{}
|
||||
}
|
||||
|
||||
// Remove removes an element from the set.
|
||||
func (s Set[T]) Remove(e T) {
|
||||
delete(s, e)
|
||||
}
|
||||
|
||||
// Contains returns true if the set contains the element.
|
||||
func (s Set[T]) Contains(e T) bool {
|
||||
_, ok := s[e]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Diff returns the difference between two sets.
|
||||
func (s Set[T]) Diff(other Set[T]) Set[T] {
|
||||
diff := make(Set[T])
|
||||
for e := range s {
|
||||
if !other.Contains(e) {
|
||||
diff.Add(e)
|
||||
}
|
||||
}
|
||||
return diff
|
||||
}
|
||||
|
||||
// Union returns the union of two sets.
|
||||
func (s Set[T]) Union(other Set[T]) Set[T] {
|
||||
union := make(Set[T])
|
||||
for e := range s {
|
||||
union.Add(e)
|
||||
}
|
||||
for e := range other {
|
||||
union.Add(e)
|
||||
}
|
||||
return union
|
||||
}
|
||||
|
||||
// Intersect returns the intersection of two sets.
|
||||
func (s Set[T]) Intersect(other Set[T]) Set[T] {
|
||||
intersect := make(Set[T])
|
||||
for e := range s {
|
||||
if other.Contains(e) {
|
||||
intersect.Add(e)
|
||||
}
|
||||
}
|
||||
return intersect
|
||||
}
|
||||
|
||||
// Subset returns true if the set is a subset of the other set.
|
||||
func (s Set[T]) Subset(other Set[T]) bool {
|
||||
for e := range s {
|
||||
if !other.Contains(e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if the set is equal to the other set.
|
||||
func (s Set[T]) Equal(other Set[T]) bool {
|
||||
return s.Subset(other) && other.Subset(s)
|
||||
}
|
||||
|
||||
// ToSlice returns the set as a slice.
|
||||
func (s Set[T]) ToSlice() []T {
|
||||
return maps.Keys(s)
|
||||
}
|
||||
|
||||
// SetDiff returns all the items that are in the first set but not in the
|
||||
// second.
|
||||
func SetDiff[T comparable](a, b []T) []T {
|
||||
setA := NewSet(a...)
|
||||
setB := NewSet(b...)
|
||||
|
||||
return setA.Diff(setB).ToSlice()
|
||||
}
|
Reference in New Issue
Block a user