fn: add new generic set container

This commit is contained in:
Olaoluwa Osuntokun 2024-01-02 17:18:59 -08:00
parent eb72bb9712
commit 1fc3f14467
No known key found for this signature in database
GPG key ID: 3BBD59E99B280306
3 changed files with 101 additions and 1 deletions

View file

@ -2,4 +2,7 @@ module github.com/lightningnetwork/lnd/fn
go 1.19
require github.com/lightninglabs/neutrino/cache v1.1.2
require (
github.com/lightninglabs/neutrino/cache v1.1.2
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b
)

View file

@ -3,4 +3,6 @@ github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3
github.com/lightninglabs/neutrino/cache v1.1.2/go.mod h1:XJNcgdOw1LQnanGjw8Vj44CvguYA25IMKjWFZczwZuo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

95
fn/set.go Normal file
View 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()
}