sets

package
v1.10.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2024 License: MIT Imports: 2 Imported by: 0

README

genesis/sets

Package sets provides generic functions for sets.

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

Examples

Constants

This section is empty.

Variables

View Source
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

func Max[S ~map[K]Z, K c.Ordered](set S) (K, error)
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

func Min[S ~map[K]Z, K c.Ordered](set S) (K, error)
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

func Sum[S ~map[K]Z, K c.Integer | c.Float](set S) K

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:{}]

Types

type Z

type Z = struct{}

Z is a zero type used as the map value for sets.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL