Documentation
¶
Overview ¶
⚙️ Package sets provides generic functions for sets.
By convention, a set in go is represented as map[T]struct{} where T is the set element type. It allows to ensure that each element of the set appears only once, and using struct{} allows to not spend any memory on the map values.
Using maps instead of a specifically deisigned for sets data structures means that some operations, like Union, aren't as fast as they potentially could be. However, we decided to stick to maps instead of introducing a new data type to avoid vendor lock on genesis and simplify iteration over elements.
Index ¶
- Variables
- func Add[S ~map[K]Z, K comparable](set S, value K)
- func Clear[S ~map[K]Z, K comparable](set S)
- func Contains[S ~map[K]Z, K comparable](set S, item K) bool
- func Copy[S ~map[K]Z, K comparable](set S) S
- func Difference[S1, S2 ~map[K]Z, K comparable](first S1, second S2) map[K]Z
- func Discard[S ~map[K]Z, K comparable](set S, value K)
- func Disjoint[S1, S2 ~map[K]Z, K comparable](first S1, second S2) bool
- func DisjointMany[S ~map[K]Z, K comparable](sets ...S) bool
- func Empty[S ~map[K]Z, K comparable](set S) bool
- func Equal[S1, S2 ~map[K]Z, K comparable](first S1, second S2) bool
- func EqualMany[S ~map[K]Z, K comparable](sets ...S) bool
- func Filter[S ~map[K]Z, K comparable](set S, f func(K) bool) S
- func FromSlice[S ~[]K, K comparable](items S) map[K]Z
- func Intersect[S1, S2 ~map[K]Z, K comparable](first S1, second S2) bool
- func Intersection[S1, S2 ~map[K]Z, K comparable](first S1, second S2) map[K]Z
- func Map[S ~map[K]Z, K, R comparable](set S, f func(K) R) map[R]Z
- func Max[S ~map[K]Z, K c.Ordered](set S) (K, error)
- func Min[S ~map[K]Z, K c.Ordered](set S) (K, error)
- func New[K comparable](values ...K) map[K]Z
- func Pop[S ~map[K]Z, K comparable](set S) (K, error)
- func Reduce[S ~map[K]Z, K comparable, R any](set S, acc R, f func(K, R) R) R
- func Subset[S1, S2 ~map[K]Z, K comparable](small S1, big S2) bool
- func Sum[S ~map[K]Z, K c.Integer | c.Float](set S) K
- func Superset[S1, S2 ~map[K]Z, K comparable](big S1, small S2) bool
- func SymmetricDifference[S1, S2 ~map[K]Z, K comparable](first S1, second S2) map[K]Z
- func ToSlice[S ~map[K]Z, K comparable](set S) []K
- func Union[S1, S2 ~map[K]Z, K comparable](first S1, second S2) map[K]Z
- func UnionMany[S ~map[K]Z, K comparable](sets ...S) map[K]Z
- func Update[S1, S2 ~map[K]Z, K comparable](target S1, values S2)
- type Z
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrEmpty = errors.New("container is empty")
ErrEmpty is an error for empty set when it's expected to have elements
Functions ¶
func Add ¶
func Add[S ~map[K]Z, K comparable](set S, value K)
Add adds the given element in the set.
If the element already in the set, nothing happens.
If the set is nil, the function will panic.
The set is modified in place.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 4)
sets.Add(s, 4)
sets.Add(s, 5)
fmt.Println(s)
}
Output: map[3:{} 4:{} 5:{}]
func Clear ¶
func Clear[S ~map[K]Z, K comparable](set S)
Clear removes all elements from the set.
The set is modified in place.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 4)
sets.Clear(s)
fmt.Println(s)
}
Output: map[]
func Contains ¶
func Contains[S ~map[K]Z, K comparable](set S, item K) bool
Contains returns true if the given set contains the given element.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 4, 5)
result := sets.Contains(s, 4)
fmt.Println(result)
}
Output: true
func Copy ¶
func Copy[S ~map[K]Z, K comparable](set S) S
Copy returns a shallow copy of the given set.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4)
b := sets.Copy(a)
sets.Add(a, 5)
sets.Add(b, 6)
fmt.Println(a)
fmt.Println(b)
}
Output: map[3:{} 4:{} 5:{}] map[3:{} 4:{} 6:{}]
func Difference ¶
func Difference[S1, S2 ~map[K]Z, K comparable](first S1, second S2) map[K]Z
Difference returns a set containing elements that appear in the first set but not in the second.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5)
b := sets.New(5, 6, 7)
result := sets.Difference(a, b)
fmt.Println(result)
}
Output: map[3:{} 4:{}]
func Discard ¶
func Discard[S ~map[K]Z, K comparable](set S, value K)
Discard removes the given element from the set.
If the element already not in the set, nothing happens.
The set is modified in place.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 4)
sets.Discard(s, 4)
sets.Discard(s, 5)
fmt.Println(s)
}
Output: map[3:{}]
func Disjoint ¶
func Disjoint[S1, S2 ~map[K]Z, K comparable](first S1, second S2) bool
Disjoint returns true if the two given sets don't have any common elements.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5)
b := sets.New(5, 6, 7)
result := sets.Disjoint(a, b)
fmt.Println(result) // a and b both share 5
}
Output: false
func DisjointMany ¶
func DisjointMany[S ~map[K]Z, K comparable](sets ...S) bool
DisjointMany returns true if the given sets don't have any common elements.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4)
b := sets.New(5, 6)
c := sets.New(6, 7)
result := sets.DisjointMany(a, b, c)
fmt.Println(result) // b and c both share 6
}
Output: false
func Empty ¶
func Empty[S ~map[K]Z, K comparable](set S) bool
Empty returns true if the set has no elements
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New[int]()
result := sets.Empty(s)
fmt.Println(result)
}
Output: true
func Equal ¶
func Equal[S1, S2 ~map[K]Z, K comparable](first S1, second S2) bool
Equal returns true if both given sets have the same elements.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5)
b := sets.New(3, 4, 6)
result := sets.Equal(a, b)
fmt.Println(result)
}
Output: false
func EqualMany ¶
func EqualMany[S ~map[K]Z, K comparable](sets ...S) bool
EqualMany returns true if all the given sets have the same elements.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5)
b := sets.New(3, 4, 5)
c := sets.New(3, 4, 6)
result := sets.EqualMany(a, b, c)
fmt.Println(result)
}
Output: false
func Filter ¶
func Filter[S ~map[K]Z, K comparable](set S, f func(K) bool) S
Filter returns elements of the set for which the given function returns true.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 4, 5, 6, 7, 8)
even := func(x int) bool { return x%2 == 0 }
result := sets.Filter(s, even)
fmt.Println(result)
}
Output: map[4:{} 6:{} 8:{}]
func FromSlice ¶
func FromSlice[S ~[]K, K comparable](items S) map[K]Z
FromSlice converts a slice into a set.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := []int{3, 4, 5}
result := sets.FromSlice(s)
fmt.Println(result)
}
Output: map[3:{} 4:{} 5:{}]
func Intersect ¶
func Intersect[S1, S2 ~map[K]Z, K comparable](first S1, second S2) bool
Intersect returns true if the two given sets have at least one common element.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5)
b := sets.New(5, 6, 7)
result := sets.Intersect(a, b)
fmt.Println(result)
}
Output: true
func Intersection ¶
func Intersection[S1, S2 ~map[K]Z, K comparable](first S1, second S2) map[K]Z
Intersection returns a set containing elements that appear in both of the given sets.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5)
b := sets.New(4, 5, 6)
result := sets.Intersection(a, b)
fmt.Println(result)
}
Output: map[4:{} 5:{}]
func Map ¶
func Map[S ~map[K]Z, K, R comparable](set S, f func(K) R) map[R]Z
Map applies the given function to each element of the set and returns a set of results.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 4, 5)
double := func(x int) int { return x * 2 }
result := sets.Map(s, double)
fmt.Println(result)
}
Output: map[6:{} 8:{} 10:{}]
func Max ¶
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 6, 4, 5)
result, _ := sets.Max(s)
fmt.Println(result)
}
Output: 6
func Min ¶
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(4, 5, 3, 6)
result, _ := sets.Min(s)
fmt.Println(result)
}
Output: 3
func New ¶
func New[K comparable](values ...K) map[K]Z
New is a convenience function for constructing a set from a list of values.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
result := sets.New(3, 4, 4, 5, 3)
fmt.Println(result)
}
Output: map[3:{} 4:{} 5:{}]
func Pop ¶
func Pop[S ~map[K]Z, K comparable](set S) (K, error)
Pop removes an element from the set and returns that element.
If the set is empty, ErrEmpty is returned.
The set is modified in place.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(4)
val, _ := sets.Pop(s)
fmt.Println(val, s)
}
Output: 4 map[]
func Reduce ¶
func Reduce[S ~map[K]Z, K comparable, R any](set S, acc R, f func(K, R) R) R
Reduce applies the function to acc and every set element and returns the acc.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 4, 5)
add := func(x, acc int) int { return x + acc }
result := sets.Reduce(s, 0, add)
fmt.Println(result)
}
Output: 12
func Subset ¶
func Subset[S1, S2 ~map[K]Z, K comparable](small S1, big S2) bool
Subset returns true if the first set is a subset of the second one.
One set is called a subset of another if all its elements are included in that set.
This function is the same as Superset but with inversed argument order. Which one to use is a matter of readability.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(4, 5)
b := sets.New(3, 4, 5, 6)
result := sets.Subset(a, b)
fmt.Println(result)
}
Output: true
func Sum ¶
Sum returns the sum of all elements of the set.
If the set is empty, 0 is returned.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3, 4, 5)
result := sets.Sum(s)
fmt.Println(result)
}
Output: 12
func Superset ¶
func Superset[S1, S2 ~map[K]Z, K comparable](big S1, small S2) bool
Superset returns true if the first set is a superset of the second one.
One set is called a superset of another if it includes all elements of that set.
This function is the same as Subset but with inversed argument order. Which one to use is a matter of readability.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5, 6)
b := sets.New(4, 5)
result := sets.Superset(a, b)
fmt.Println(result)
}
Output: true
func SymmetricDifference ¶
func SymmetricDifference[S1, S2 ~map[K]Z, K comparable](first S1, second S2) map[K]Z
SymmetricDifference returns a set containing elements that appear only in one set but not both.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5)
b := sets.New(5, 6, 7)
result := sets.SymmetricDifference(a, b)
fmt.Println(result)
}
Output: map[3:{} 4:{} 6:{} 7:{}]
func ToSlice ¶
func ToSlice[S ~map[K]Z, K comparable](set S) []K
ToSlice converts the set to a slice.
The order of elements in the resulting set is semi-random.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
s := sets.New(3)
result := sets.ToSlice(s)
fmt.Println(result)
}
Output: [3]
func Union ¶
func Union[S1, S2 ~map[K]Z, K comparable](first S1, second S2) map[K]Z
Union returns a set containing all elements from both of the given sets.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4, 5)
b := sets.New(5, 6, 7)
result := sets.Union(a, b)
fmt.Println(result)
}
Output: map[3:{} 4:{} 5:{} 6:{} 7:{}]
func UnionMany ¶
func UnionMany[S ~map[K]Z, K comparable](sets ...S) map[K]Z
UnionMany returns a set containing all elements from all the given sets.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(3, 4)
b := sets.New(5, 6)
c := sets.New(6, 7)
result := sets.UnionMany(a, b, c)
fmt.Println(result)
}
Output: map[3:{} 4:{} 5:{} 6:{} 7:{}]
func Update ¶
func Update[S1, S2 ~map[K]Z, K comparable](target S1, values S2)
Update adds elements from the values set into the target set.
If the target set is nil and the values set is not empty, the function will panic.
The set is modified in place. If you don't want to modify the set, use Union instead.
Example ¶
package main
import (
"fmt"
"github.com/life4/genesis/sets"
)
func main() {
a := sets.New(4, 5)
b := sets.New(5, 6)
sets.Update(a, b)
fmt.Println(a)
}
Output: map[4:{} 5:{} 6:{}]