Documentation
¶
Overview ¶
Package iterset is a set library based on maps and iterators.
Example (Intersect) ¶
Intersect a map with a slice of keys, retaining original order.
data := map[string]int{"a": 0, "b": 1, "c": 2} keys := []string{"d", "c", "b"} // With no sets. for _, key := range keys { value, ok := data[key] if ok { fmt.Println(key, value) } } // A typical `mapset` would copy `data`, and have no impact on readability. s := Set(slices.Collect(maps.Keys(data))...) for _, key := range keys { if s.Contains(key) { fmt.Println(key, data[key]) } } // Using an intersect method would also copy `keys`, and lose ordering. // Whereas `iterset` methods have in-lined logic with zero copying and lazy iteration. for key, value := range Cast(data).Intersect(slices.Values(keys)) { fmt.Println(key, value) }
Output: c 2 b 1 c 2 b 1 c 2 b 1
Example (Superset) ¶
Is one slice a superset of another?
left, right := []string{"a", "b", "c"}, []string{"b", "c", "d"} // With no sets. m := map[string]bool{} for _, c := range left { m[c] = true } isSuperset := true for _, c := range right { if !m[c] { isSuperset = false break } } fmt.Println(isSuperset) // Or in functional style. fmt.Println(!slices.ContainsFunc(right, func(c string) bool { return !m[c] })) // A typical `mapset` would copy both slices, which makes early exits irrelevant. // Or it only solves half the problem. s := Set(left...) fmt.Println(!slices.ContainsFunc(right, func(c string) bool { return !s.Contains(c) })) // Whereas `iterset` methods have in-lined logic with minimal copying and early exits. fmt.Println(Set(left...).IsSuperset(slices.Values(right)))
Output: false false false false
Example (Unique) ¶
Remove duplicates, retaining original order.
values := []string{"a", "b", "a"} // With no sets. m := map[string]bool{} keys := []string{} for _, c := range values { if !m[c] { keys = append(keys, c) } m[c] = true } fmt.Println(keys) // A typical `mapset` would either have no impact on readability, or lose ordering. // Whereas `iterset` has this built-in with lazy iteration. for c := range Unique(slices.Values(values)) { fmt.Println(c) } // What if a `set` is still needed, in addition to ordering. idx := Index(slices.Values(values)) fmt.Println(idx) fmt.Println(Sorted(idx)) // keys sorted by value
Output: [a b] a b map[a:0 b:1] [a b]
Index ¶
- func Compact[K comparable](keys iter.Seq[K]) iter.Seq2[K, int]
- func CompactBy[K comparable, V any](values iter.Seq[V], key func(V) K) iter.Seq2[K, []V]
- func Difference[K comparable](keys iter.Seq[K], seqs ...iter.Seq[K]) iter.Seq[K]
- func Intersect[K comparable](keys iter.Seq[K], seqs ...iter.Seq[K]) iter.Seq[K]
- func IsSubset[K comparable](keys, seq iter.Seq[K]) bool
- func Max[K comparable, V cmp.Ordered](m map[K]V) []K
- func Min[K comparable, V cmp.Ordered](m map[K]V) []K
- func Sorted[K comparable, V cmp.Ordered](m map[K]V) []K
- func Unique[K comparable](keys iter.Seq[K]) iter.Seq[K]
- func UniqueBy[K comparable, V any](values iter.Seq[V], key func(V) K) iter.Seq2[K, V]
- type MapSet
- func Cast[K comparable, V any](m map[K]V) MapSet[K, V]
- func Collect[K comparable, V any](keys iter.Seq[K], value V) MapSet[K, V]
- func Count[K comparable](keys iter.Seq[K]) MapSet[K, int]
- func GroupBy[K comparable, V any](values iter.Seq[V], key func(V) K) MapSet[K, []V]
- func Index[K comparable](keys iter.Seq[K]) MapSet[K, int]
- func IndexBy[K comparable, V any](values iter.Seq[V], key func(V) K) MapSet[K, V]
- func Memoize[K comparable, V any](keys iter.Seq[K], f func(K) V) MapSet[K, V]
- func Set[K comparable](keys ...K) MapSet[K, struct{}]
- func (m MapSet[K, V]) Add(keys ...K)
- func (m MapSet[K, V]) Contains(keys ...K) bool
- func (m MapSet[K, V]) Delete(keys ...K)
- func (m MapSet[K, V]) Difference(keys iter.Seq[K]) iter.Seq2[K, V]
- func (m MapSet[K, V]) Equal(keys iter.Seq[K]) bool
- func (m MapSet[K, V]) Insert(keys iter.Seq[K], value V)
- func (m MapSet[K, V]) Intersect(keys iter.Seq[K]) iter.Seq2[K, V]
- func (m MapSet[K, V]) IsDisjoint(keys iter.Seq[K]) bool
- func (m MapSet[K, V]) IsSubset(keys iter.Seq[K]) bool
- func (m MapSet[K, V]) IsSuperset(keys iter.Seq[K]) bool
- func (m MapSet[K, V]) Remove(keys iter.Seq[K])
- func (m MapSet[K, V]) ReverseDifference(keys iter.Seq[K]) iter.Seq[K]
- func (m MapSet[K, V]) SymmetricDifference(keys iter.Seq[K]) iter.Seq[K]
- func (m MapSet[K, V]) Toggle(seq iter.Seq2[K, V])
- func (m MapSet[K, V]) Union(seqs ...iter.Seq2[K, V]) MapSet[K, V]
Examples ¶
- Package (Intersect)
- Package (Superset)
- Package (Unique)
- Collect
- Compact
- CompactBy
- Count
- Difference
- GroupBy
- Index
- IndexBy
- Intersect
- IsSubset
- MapSet.Add
- MapSet.Contains
- MapSet.Delete
- MapSet.Difference
- MapSet.Equal
- MapSet.IsDisjoint
- MapSet.IsSubset
- MapSet.IsSuperset
- MapSet.Remove
- MapSet.SymmetricDifference
- MapSet.Toggle
- MapSet.Union
- Max
- Memoize
- Min
- Sorted
- Unique
- UniqueBy
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Compact ¶ added in v0.3.0
Compact returns consecutive runs of deduplicated keys, with counts.
Related:
Example ¶
k := slices.Values([]string{"b", "b", "a", "a", "b"}) for key, count := range Compact(k) { fmt.Println(key, count) }
Output: b 2 a 2 b 1
func CompactBy ¶ added in v0.3.0
CompactBy is like Compact but uses a key function and collects all values.
Related:
Example ¶
items := []item{{id: "b"}, {id: "b"}, {id: "a"}, {id: "a"}, {id: "b"}} for key, values := range CompactBy(slices.Values(items), item.Id) { fmt.Println(key, values) }
Output: b [{b} {b}] a [{a} {a}] b [{b}]
func Difference ¶ added in v0.2.0
Difference returns the ordered keys which are not present in the sequence(s).
Related:
- MapSet.ReverseDifference if the sequence was a map
Performance:
- time: Θ(k)
- space: Θ(k)
Example ¶
s1 := slices.Values([]string{"a", "b"}) s2 := slices.Values([]string{"b", "c"}) fmt.Println(slices.Collect(Difference(s1, s2)))
Output: [a]
func Intersect ¶ added in v0.3.0
Intersect returns the ordered keys which are present in the sequence(s).
Related:
- MapSet.Intersect if the sequence was a map
Performance:
- time: Θ(k)
- space: Θ(k)
Example ¶
s1 := slices.Values([]string{"a", "b"}) s2 := slices.Values([]string{"b", "c"}) fmt.Println(slices.Collect(Intersect(s1, s2)))
Output: [b]
func IsSubset ¶ added in v0.2.0
func IsSubset[K comparable](keys, seq iter.Seq[K]) bool
IsSubset returns whether all keys are present in the sequence.
Related:
- MapSet.IsSuperset if the sequence was a map
Performance:
- time: Θ(k)
- space: Θ(k)
Example ¶
s1 := slices.Values([]string{"a"}) s2 := slices.Values([]string{"a", "b"}) fmt.Println(IsSubset(s1, s2), IsSubset(s2, s1))
Output: true false
func Max ¶ added in v0.3.0
func Max[K comparable, V cmp.Ordered](m map[K]V) []K
Max returns the key(s) with the maximum corresponding value. Will be empty only if the map is empty.
Related:
- Count to rank by frequency
Example ¶
s := Max(map[string]int{"a": 2, "b": 2, "c": 1}) slices.Sort(s) fmt.Println(s)
Output: [a b]
func Min ¶ added in v0.3.0
func Min[K comparable, V cmp.Ordered](m map[K]V) []K
Min returns the key(s) with the minimum corresponding value. Will be empty only if the map is empty.
Related:
- Count to rank by frequency
Example ¶
s := Min(map[string]int{"a": 2, "b": 1, "c": 1}) slices.Sort(s) fmt.Println(s)
Output: [b c]
func Sorted ¶
func Sorted[K comparable, V cmp.Ordered](m map[K]V) []K
Sorted returns keys ordered by corresponding value.
Related:
Example ¶
fmt.Println(Sorted(Index(slices.Values([]string{"b", "a", "b"}))))
Output: [b a]
func Unique ¶
func Unique[K comparable](keys iter.Seq[K]) iter.Seq[K]
Unique returns keys in order without duplicates.
Related:
Performance:
- time: O(k)
- space: O(k)
Example ¶
k := slices.Values([]string{"b", "a", "b"}) fmt.Println(slices.Collect(Unique(k)))
Output: [b a]
func UniqueBy ¶ added in v0.3.0
UniqueBy is like Unique but uses a key function to compare values. For values that compare equal, the first key-value pair is returned.
Related:
Performance:
- time: O(k)
- space: O(k)
Example ¶
items := []item{{id: "b"}, {id: "a"}, {id: "b"}} for key, value := range UniqueBy(slices.Values(items), item.Id) { fmt.Println(key, value) }
Output: b {b} a {a}
Types ¶
type MapSet ¶
type MapSet[K comparable, V any] map[K]V
MapSet is a `map` extended with set methods.
func Cast ¶
func Cast[K comparable, V any](m map[K]V) MapSet[K, V]
Cast returns a zero-copy MapSet. Equivalent to `MapSet[K, V](m)` without having to specify concrete types.
func Collect ¶ added in v0.2.0
func Collect[K comparable, V any](keys iter.Seq[K], value V) MapSet[K, V]
Collect returns unique keys with a default value.
Related:
- maps.Collect for an iter.Seq2
Example ¶
k := slices.Values([]string{"b", "a", "b"}) fmt.Println(Collect(k, true))
Output: map[a:true b:true]
func Count ¶
func Count[K comparable](keys iter.Seq[K]) MapSet[K, int]
Count returns unique keys with their counts.
Related:
- Compact if the keys are already grouped
Example ¶
fmt.Println(Count(slices.Values([]string{"b", "a", "b"})))
Output: map[a:1 b:2]
func GroupBy ¶
func GroupBy[K comparable, V any](values iter.Seq[V], key func(V) K) MapSet[K, []V]
GroupBy returns values grouped by key function.
Related:
Example ¶
items := []item{{id: "b"}, {id: "a"}, {id: "b"}} fmt.Println(GroupBy(slices.Values(items), item.Id))
Output: map[a:[{a}] b:[{b} {b}]]
func Index ¶
func Index[K comparable](keys iter.Seq[K]) MapSet[K, int]
Index returns unique keys with their first index position.
Related:
Example ¶
fmt.Println(Index(slices.Values([]string{"b", "a", "b"})))
Output: map[a:1 b:0]
func IndexBy ¶
func IndexBy[K comparable, V any](values iter.Seq[V], key func(V) K) MapSet[K, V]
IndexBy returns values indexed by key function. If there are collisions, the last value remains.
Related:
Example ¶
items := []item{{id: "b"}, {id: "a"}, {id: "b"}} fmt.Println(IndexBy(slices.Values(items), item.Id))
Output: map[a:{a} b:{b}]
func Memoize ¶ added in v0.2.0
func Memoize[K comparable, V any](keys iter.Seq[K], f func(K) V) MapSet[K, V]
Memoize caches function call.
Example ¶
fmt.Println(Memoize(slices.Values([]string{"b", "a", "b"}), strings.ToUpper))
Output: map[a:A b:B]
func Set ¶
func Set[K comparable](keys ...K) MapSet[K, struct{}]
Set returns unique keys with an empty struct value.
func (MapSet[K, V]) Add ¶
func (m MapSet[K, V]) Add(keys ...K)
Add key(s) with zero value.
Related:
- MapSet.Insert for many keys
Example ¶
s := Set("a", "b") s.Add("b", "c") fmt.Println(len(s))
Output: 3
func (MapSet[K, V]) Contains ¶
Contains returns whether the key(s) is present.
Related:
- MapSet.IsSuperset for many keys
Example ¶
s := Set("b", "a", "b") fmt.Println(s.Contains("a"), s.Contains("b", "c"))
Output: true false
func (MapSet[K, V]) Delete ¶
func (m MapSet[K, V]) Delete(keys ...K)
Delete key(s).
Related:
- MapSet.Remove for many keys
Example ¶
s := Set("a", "b") s.Delete("b", "c") fmt.Println(len(s))
Output: 1
func (MapSet[K, V]) Difference ¶
Difference returns the key-value pairs which are not present in the keys.
Related:
- MapSet.Remove to modify in-place
- MapSet.ReverseDifference if the keys were a map
- Difference if the receiver was not a map
Performance:
- time: O(m+k)
- space: O(min(m,k))
Example ¶
k := slices.Values([]string{"b", "c"}) fmt.Println(maps.Collect(Set("a", "b").Difference(k)))
Output: map[a:{}]
func (MapSet[K, V]) Equal ¶ added in v0.2.0
Equal returns whether the key sets are equivalent.
Related:
- maps.Equal to compare values
Performance:
- time: O(k)
- space: O(min(m, k))
Example ¶
k := slices.Values([]string{"b", "a", "b"}) fmt.Println(Set("a", "b").Equal(k), Set("a").Equal(k))
Output: true false
func (MapSet[K, V]) Insert ¶ added in v0.2.0
Insert keys with default value.
Related:
- maps.Insert for an iter.Seq2
- maps.Copy for a map
func (MapSet[K, V]) Intersect ¶
Intersect returns the ordered key-value pairs which are present in both.
Performance:
- time: O(k)
func (MapSet[K, V]) IsDisjoint ¶
IsDisjoint returns whether no keys are present.
Performance:
- time: O(k)
Example ¶
k := slices.Values([]string{"b", "a", "b"}) fmt.Println(Set("c").IsDisjoint(k), Set("a").IsDisjoint(k))
Output: true false
func (MapSet[K, V]) IsSubset ¶ added in v0.2.0
IsSubset returns whether every map key is present in keys.
Related:
- MapSet.IsSuperset if the keys were a map
- IsSubset if the receiver was not a map
Performance:
- time: O(k)
- space: O(min(m, k))
Example ¶
k := slices.Values([]string{"b", "a", "b"}) fmt.Println(Set("a").IsSubset(k), Set("a", "c").IsSubset(k))
Output: true false
func (MapSet[K, V]) IsSuperset ¶
IsSuperset returns whether all keys are present.
Performance:
- time: O(k)
Example ¶
k := slices.Values([]string{"b", "a", "b"}) fmt.Println(Set("a", "b").IsSuperset(k), Set("a").IsSuperset(k))
Output: true false
func (MapSet[K, V]) Remove ¶ added in v0.3.0
Remove keys.
Related:
- MapSet.Difference to not modify in-place
Example ¶
s := Set("a", "b") s.Remove(slices.Values([]string{"b", "c"})) fmt.Println(s)
Output: map[a:{}]
func (MapSet[K, V]) ReverseDifference ¶ added in v0.2.0
ReverseDifference returns the ordered keys which are not present in the map. Also known as the relative complement.
- time: O(k)
func (MapSet[K, V]) SymmetricDifference ¶ added in v0.2.0
SymmetricDifference returns keys which are not in both.
Related:
- MapSet.Toggle to modify in-place
Performance:
- time: O(m+k)
- space: O(min(m, k))
Example ¶
k := slices.Values([]string{"b", "c"}) fmt.Println(slices.Collect(Set("a", "b").SymmetricDifference(k)))
Output: [c a]
func (MapSet[K, V]) Toggle ¶ added in v0.3.0
Toggle removes present keys, and inserts missing keys.
Related:
- MapSet.SymmetricDifference to not modify in-place
Example ¶
s := Set("a", "b") s.Toggle(maps.All(Set("b", "c"))) fmt.Println(s)
Output: map[a:{} c:{}]
func (MapSet[K, V]) Union ¶ added in v0.2.0
Union merges all keys with successive inserts.
Related:
- maps.Insert to modify in-place
Performance:
- time: Θ(m+k)
- space: Ω(max(m, k))..O(m+k)
Example ¶
m := map[string]int{"a": 0, "b": 1} n := map[string]int{"b": 2, "c": 3} fmt.Println(Cast(m).Union(maps.All(n)))
Output: map[a:0 b:2 c:3]