mapset

package module
v0.0.0-...-672e1cf Latest Latest
Warning

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

Go to latest
Published: May 4, 2024 License: BSD-2-Clause Imports: 0 Imported by: 0

README

mapset

Go Reference

go get github.com/jimmyfrasche/mapset

Package mapset implements set-like operations for maps. This generalizes the existing pattern of map[K]bool using a ContainsFunc predicate in place of a bool.

These operations treat maps as sets defined by their keys that happen to have some associated values that are taken along for the ride. When multiple values need to be considered for the same key a MergeFunc defines what value that key takes.

The Set and Bool types package these operations into types that can be used by conversion from a map[K]struct{} or map[K]bool, respectively.


Automatically generated by autoreadme

Documentation

Overview

Package mapset implements set-like operations for maps. This generalizes the existing pattern of map[K]bool using a ContainsFunc predicate in place of a bool.

These operations treat maps as sets defined by their keys that happen to have some associated values that are taken along for the ride. When multiple values need to be considered for the same key a MergeFunc defines what value that key takes.

The Set and Bool types package these operations into types that can be used by conversion from a map[K]struct{} or map[K]bool, respectively.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Clone

func Clone[K comparable, V any, M ~map[K]V](m M, contains ContainsFunc[V]) M

Clone returns a copy of M without items that fail the ContainsFunc check.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	x := map[string]int{"a": -1, "b": 0, "c": 1}

	contains := func(n int) bool {
		return n >= 0
	}

	// this is the same behavior of maps.Clone
	y := mapset.Clone(x, nil)

	// this clone will not contain "a" as -1 fails the contains check
	z := mapset.Clone(x, contains)

	fmt.Println("y:", y)
	fmt.Println("z:", z)

}
Output:

y: map[a:-1 b:0 c:1]
z: map[b:0 c:1]

func Contains

func Contains[K comparable, V any, M ~map[K]V](m M, key K, contains ContainsFunc[V]) bool

Contains returns false if key is not in the set m.

If the key is not in the map m, Contains returns false.

If the key is in the map, Contains returns the result of contains.Check.

Everything in this package that accepts a ContainsFunc applies the same logic.

func Diff

func Diff[K comparable, V any, M ~map[K]V](lhs, rhs M, contains ContainsFunc[V]) M

Diff is the set difference of lhs and rhs. The result contains all items in lhs that pass the ContainsFunc check that are not in rhs. Diff is also known as: relative complement, kick out, or except.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	x := map[string]int{"a": 0, "b": 1, "d": -5}
	y := map[string]int{"b": 2, "c": 1, "d": 5}

	z := mapset.Diff(x, y, nil)
	fmt.Println(z)

}
Output:

map[a:0]

func Disjoint

func Disjoint[K comparable, V any, M ~map[K]V](lhs, rhs M, contains ContainsFunc[V]) bool

Disjoint returns true if no keys of lhs are present in rhs.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	x := map[string]int{"a": 0, "b": 1, "d": -5}
	y := map[string]int{"b": 1, "e": 5, "f": 7}

	fmt.Println("nil contains:", mapset.Disjoint(x, y, nil))

	// b: 1 is the only kv-pair in both maps
	// so this leaves them with disjoint key-sets
	contains := func(n int) bool {
		return n != 1
	}

	fmt.Println("contains removes 1s:", mapset.Disjoint(x, y, contains))

}
Output:

nil contains: false
contains removes 1s: true

func Equal

func Equal[K comparable, V any, M ~map[K]V](lhs, rhs M, contains ContainsFunc[V]) bool

Equal tests equality of the keys whose values pass the ContainsFunc check. The values are otherwise not considered.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	a := map[string]int{"a": 4, "b": 7, "c": -1}
	b := map[string]int{"a": 3, "b": 2, "c": 11}
	c := map[string]int{"b": 2, "c": 11, "d": 86}

	if mapset.Equal(a, b, nil) {
		fmt.Println("a = b")
	}

	if !mapset.Equal(a, c, nil) {
		fmt.Println("a != c")
	}

	contains := func(x int) bool {
		return x >= 0
	}

	if !mapset.Equal(a, b, contains) {
		fmt.Println("a != b as contains removes a[c]")
	}

}
Output:

a = b
a != c
a != b as contains removes a[c]

func Intersect

func Intersect[K comparable, V any, M ~map[K]V](lhs, rhs M, contains ContainsFunc[V], merge MergeFunc[V]) M

Intersect creates a new M that is the intersection of lhs and rhs. All pairs values pass ContainsFunc, are merged, and the result passes the ContainsFunc for inclusion.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	x := map[string]int{"a": 0, "b": 1, "d": -5}
	y := map[string]int{"b": 2, "c": 1, "d": 5}

	z := mapset.Intersect(x, y, nil, nil)
	fmt.Println(z)

}
Output:

map[b:1 d:-5]

func Keys

func Keys[K comparable, V any, M ~map[K]V](m M, contains ContainsFunc[V]) []K

Keys collects all the the keys whose corresponding values pass the ContainsFunc check.

Example
package main

import (
	"fmt"
	"sort"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	m := map[string]bool{"a": true, "b": true, "c": false, "d": true}

	contains := func(b bool) bool {
		return b
	}

	k := mapset.Keys(m, contains)

	sort.Strings(k)

	fmt.Println("k:", k)

}
Output:

k: [a b d]

func Len

func Len[K comparable, V any, M ~map[K]V](m M, contains ContainsFunc[V]) int

Len counts the keys in m whose values pass the ContainsFunc check.

func ProperSubset

func ProperSubset[K comparable, V any, M ~map[K]V](lhs, rhs M, contains ContainsFunc[V]) bool

ProperSubset checks that lhs Subset rhs but not lhs Equal rhs.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	a := map[string]int{"a": 4, "b": 7}
	b := map[string]int{"a": 3, "b": 2, "c": 1}

	if mapset.ProperSubset(a, b, nil) {
		fmt.Println("the keys of a are a proper subset of the keys of b")
	}

	if !mapset.ProperSubset(a, a, nil) {
		fmt.Println("a is not a proper subset of a")
	}

	if !mapset.ProperSubset(b, a, nil) {
		fmt.Println("the keys of b are not a proper subset of the keys of a")
	}

}
Output:

the keys of a are a proper subset of the keys of b
a is not a proper subset of a
the keys of b are not a proper subset of the keys of a

func Purge

func Purge[K comparable, V any, M ~map[K]V](m M, contains ContainsFunc[V])

Purge removes all keys who fail the ContainsFunc check.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	x := map[string]int{"a": -1, "b": 0, "c": 1}

	// this is a noop as there is nothing to purge
	mapset.Purge(x, nil)

	fmt.Println("nil contains:", x)

	contains := func(n int) bool {
		return n >= 0
	}

	// this deleted "a" from x
	mapset.Purge(x, contains)

	fmt.Println("nonnil contains:", x)

}
Output:

nil contains: map[a:-1 b:0 c:1]
nonnil contains: map[b:0 c:1]

func Subset

func Subset[K comparable, V any, M ~map[K]V](lhs, rhs M, contains ContainsFunc[V]) bool

Subset tests whether lhs is a Subset of rhs.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	a := map[string]int{"a": 4, "b": 7}
	b := map[string]int{"a": 3, "b": 2, "c": 1}

	if mapset.Subset(a, b, nil) {
		fmt.Println("the keys of a are a subset of the keys of b")
	}

	if mapset.Subset(a, a, nil) {
		fmt.Println("a is a subset of a")
	}

	if !mapset.Subset(b, a, nil) {
		fmt.Println("the keys of b are not a subset of the keys of a")
	}

}
Output:

the keys of a are a subset of the keys of b
a is a subset of a
the keys of b are not a subset of the keys of a

func SymDiff

func SymDiff[K comparable, V any, M ~map[K]V](lhs, rhs M, contains ContainsFunc[V]) M

SymDiff is the symmetric difference of lhs and rhs. The results contains the values in lhs and rhs but not in both, according to the ContainsFunc check.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	x := map[string]int{"a": 0, "b": 1, "d": -5}
	y := map[string]int{"b": 2, "c": 1, "d": 5, "e": 7}

	contains := func(n int) bool {
		return n >= 0
	}

	// z has d:5 because the "d" in x is skipped by contains.Check.
	z := mapset.SymDiff(x, y, contains)
	fmt.Println("z:", z)

	zp := mapset.SymDiff(x, y, nil)
	fmt.Println("zp:", zp)

}
Output:

z: map[a:0 c:1 d:5 e:7]
zp: map[a:0 c:1 e:7]

func Union

func Union[K comparable, V any, M ~map[K]V](lhs, rhs M, contains ContainsFunc[V], merge MergeFunc[V]) M

Union creates a new M that is the union of lhs and rhs. For an item of either map to be included the value of the item must pass the ContainsFunc check. When an item exists in both maps the pair of values is merged and added to the result map if the merged value passes the ContainsFunc check.

Example
package main

import (
	"fmt"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	x := map[string]int{"a": 0, "b": 1, "d": -5}
	y := map[string]int{"b": 2, "c": 1, "d": 5}

	contains := func(n int) bool {
		return n != 0
	}

	merge := func(a, b int) int {
		return a + b
	}

	// our contains func discards "a" from x
	// our merge func makes "b" 3 in the resulting map
	// For "d" the merge func results in a value that does not pass the contains check,
	// so it is not included in z.

	z := mapset.Union(x, y, contains, merge)
	fmt.Println("z:", z)

	// with the default contains and merge, no items are discarded and the values
	// for keys in both default to the values in x.
	zp := mapset.Union(x, y, nil, nil)
	fmt.Println("zp:", zp)

}
Output:

z: map[b:3 c:1]
zp: map[a:0 b:1 c:1 d:-5]

func Values

func Values[K comparable, V any, M ~map[K]V](m M, contains ContainsFunc[V]) []V

Values collects all the values in m that pass the ContainsFunc check.

Example
package main

import (
	"fmt"
	"sort"

	"github.com/jimmyfrasche/mapset"
)

func main() {
	m := map[int]string{0: "a", 1: "b", 2: "c"}

	contains := func(s string) bool {
		return s != "a"
	}

	v := mapset.Values(m, contains)

	sort.Strings(v)

	fmt.Println("v:", v)
}
Output:

v: [b c]

Types

type Bool

type Bool[K comparable] map[K]bool

Bool provides all relevant set methods with identity as the ContainsFunc and disjunction as the MergeFunc.

func (Bool[K]) Add

func (b Bool[K]) Add(key K) bool

Add key and reports whether it is new.

func (Bool[K]) Clone

func (b Bool[K]) Clone() Bool[K]

func (Bool[K]) Contains

func (b Bool[K]) Contains(k K) bool

func (Bool[K]) Delete

func (b Bool[K]) Delete(key K) bool

Delete removes key and reports if it was present.

func (Bool[K]) Diff

func (b Bool[K]) Diff(o Bool[K]) Bool[K]

func (Bool[K]) Disjoint

func (b Bool[K]) Disjoint(o Bool[K]) bool

func (Bool[K]) Equal

func (b Bool[K]) Equal(o Bool[K]) bool

func (Bool[K]) Extend

func (b Bool[K]) Extend(keys ...K)

Extend adds keys to b.

func (Bool[K]) Intersect

func (b Bool[K]) Intersect(o Bool[K]) Bool[K]

func (Bool[K]) Keys

func (b Bool[K]) Keys() []K

func (Bool[K]) Len

func (b Bool[K]) Len() int

func (Bool[K]) ProperSubset

func (b Bool[K]) ProperSubset(o Bool[K]) bool

func (Bool[K]) Purge

func (b Bool[K]) Purge()

func (Bool[K]) Remove

func (b Bool[K]) Remove(keys ...K)

Remove keys from b.

func (Bool[K]) Subset

func (b Bool[K]) Subset(o Bool[K]) bool

func (Bool[K]) SymDiff

func (b Bool[K]) SymDiff(o Bool[K]) Bool[K]

func (Bool[K]) Union

func (b Bool[K]) Union(o Bool[K]) Bool[K]

type ContainsFunc

type ContainsFunc[V any] func(V) bool

ContainsFunc decides if an item belongs to a set based on its value. A nil ContainsFunc always returns true.

ContainsFunc generalizes the pattern of letting a map[K]bool contain an item only if m[k] is true.

See Contains.

func (ContainsFunc[V]) Check

func (c ContainsFunc[V]) Check(v V) bool

Check calls c with v or returns true if c is nil.

type MergeFunc

type MergeFunc[V any] func(lhs, rhs V) V

MergeFunc takes two V and merges them into a single value. A nil MergeFunc always returns the lhs value.

MergeFunc is used for combining the values of a key that exists in two maps that are being combined in some way.

When used with a ContainsFunc, both lhs and rhs will have passed the check before the MergeFunc is called and the resulting value is also checked.

func (MergeFunc[V]) Into

func (m MergeFunc[V]) Into(lhs, rhs V) V

Into returns m(lhs, rhs) or lhs if m == nil.

type Set

type Set[K comparable] map[K]struct{}

Set provides all relevant set methods with nil ContainsFunc and MergeFunc.

func (Set[K]) Add

func (s Set[K]) Add(key K) bool

Add key and reports whether it is new.

func (Set[K]) Contains

func (s Set[K]) Contains(k K) bool

func (Set[K]) Delete

func (s Set[K]) Delete(key K) bool

Delete removes key and reports if it was present.

func (Set[K]) Diff

func (s Set[K]) Diff(o Set[K]) Set[K]

func (Set[K]) Disjoint

func (s Set[K]) Disjoint(o Set[K]) bool

func (Set[K]) Equal

func (s Set[K]) Equal(o Set[K]) bool

func (Set[K]) Extend

func (s Set[K]) Extend(keys ...K)

Extend adds keys to s.

func (Set[K]) Intersect

func (s Set[K]) Intersect(o Set[K]) Set[K]

func (Set[K]) ProperSubset

func (s Set[K]) ProperSubset(o Set[K]) bool

func (Set[K]) Remove

func (s Set[K]) Remove(keys ...K)

Remove keys from s.

func (Set[K]) Subset

func (s Set[K]) Subset(o Set[K]) bool

func (Set[K]) SymDiff

func (s Set[K]) SymDiff(o Set[K]) Set[K]

func (Set[K]) Union

func (s Set[K]) Union(o Set[K]) Set[K]

Directories

Path Synopsis
Package multiset uses the primitives in mapset to implement a simple multiset.
Package multiset uses the primitives in mapset to implement a simple multiset.

Jump to

Keyboard shortcuts

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