gmap

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 4, 2025 License: Apache-2.0 Imports: 9 Imported by: 4

Documentation

Overview

Package gmap provides generic operations for maps.

💡 HINT: We provide similar functionality for different types in different packages. For example, github.com/bytedance/gg/gslice.Clone for copying slice while Clone for copying map.

Operations

Keys / Values getter:

High-order functions:

CRUD operations:

Partition operations:

Math operations:

Set operations:

Type casting/assertion/conversion:

Predicates:

Interface type satisfies comparable constraint after Go1.20 and later

According Go1.20 Language Change, Comparable types (such as ordinary interfaces) may now satisfy comparable constraints, even if the type arguments are not strictly comparable (comparison may PANIC at runtime).

Which means operations of gmap can be used on more map types, for example:

var m map[io.Reader]string
readers = gmap.Keys (m)
// Go1.19 and earlier:	❌ io.Reader does not implement comparable
// Go1.20 and later:	✔️ running well

It also means gmap operations may PANIC at runtime:

// Implement io.Reader for unhashable.
type unhashable []int
func (unhashable) Read([]byte) (_ int, _ error) { return }

m := make(map[io.Reader]string)
key := io.Reader(unhashable{})
_, _ = gmap.LoadOrStore(m, key, "")
// Go1.19 and earlier:	❌ io.Reader does not implement comparable
// Go1.20 and later:	❌ panic: runtime error: hash of unhashable type main.unhashable

Conflict resolution

When operating on multiple maps, key conflicts often occur, the newer value replace the old by default (DiscardOld). These operations include but are not limited to Invert, Union, Intersect and so on…

We provide ConflictFunc to help user to customize conflict resolution. All of above operations supports variant with ConflictFunc support:

Example
// Keys / Values getter
fmt.Println(Keys(map[int]int{1: 2}))                             // [1]
fmt.Println(Values(map[int]int{1: 2}))                           // [2]
fmt.Println(Items(map[int]int{1: 2}).Unzip())                    // [1] [2]
fmt.Println(OrderedKeys(map[int]int{1: 2, 2: 3, 3: 4}))          // [1, 2, 3]
fmt.Println(OrderedValues(map[int]int{1: 2, 2: 3, 3: 4}))        // [2, 3, 4]
fmt.Println(OrderedItems(map[int]int{1: 2, 2: 3, 3: 4}).Unzip()) // [1, 2, 3] [2, 3, 4]
f := func(k, v int) string { return strconv.Itoa(k) + ":" + strconv.Itoa(v) }
fmt.Println(ToSlice(map[int]int{1: 2}, f))                    // ["1:2"]
fmt.Println(ToOrderedSlice(map[int]int{1: 2, 2: 3, 3: 4}, f)) // ["1:2", "2:3", "3:4"]

// High-order function
fmt.Println(gson.ToString(Map(map[int]int{1: 2, 2: 3, 3: 4}, func(k int, v int) (string, string) {
	return strconv.Itoa(k), strconv.Itoa(k + 1)
}))) // {"1":"2", "2":"3", "3":"4"}
fmt.Println(gson.ToString(Filter(map[int]int{1: 2, 2: 3, 3: 4}, func(k int, v int) bool {
	return k+v > 3
}))) // {"2":2, "3":3}

// CRUD operation
fmt.Println(Contains(map[int]int{1: 2, 2: 3, 3: 4}, 1))           // true
fmt.Println(ContainsAny(map[int]int{1: 2, 2: 3, 3: 4}, 1, 4))     // true
fmt.Println(ContainsAll(map[int]int{1: 2, 2: 3, 3: 4}, 1, 4))     // false
fmt.Println(Load(map[int]int{1: 2, 2: 3, 3: 4}, 1).Value())       // 2
fmt.Println(LoadAny(map[int]int{1: 2, 2: 3, 3: 4}, 1, 4).Value()) // 2
fmt.Println(LoadAll(map[int]int{1: 2, 2: 3, 3: 4}, 1, 4))         // []
fmt.Println(LoadSome(map[int]int{1: 2, 2: 3, 3: 4}, 1, 4))        // [2]

// Partion operation
Chunk(map[int]int{1: 2, 2: 3, 3: 4, 4: 5, 5: 6}, 2)  // possible output: [{1:2, 2:3}, {3:4, 4:5}, {5:6}]
Divide(map[int]int{1: 2, 2: 3, 3: 4, 4: 5, 5: 6}, 2) // possible output: [{1:2, 2:3, 3:4}, {4:5, 5:6}]

// Math operation
fmt.Println(Max(map[int]int{1: 2, 2: 3, 3: 4}).Value())             // 4
fmt.Println(Min(map[int]int{1: 2, 2: 3, 3: 4}).Value())             // 2
fmt.Println(MinMax(map[int]int{1: 2, 2: 3, 3: 4}).Value().Values()) // 2 4
fmt.Println(Sum(map[int]int{1: 2, 2: 3, 3: 4}))                     // 9

// Set operation
fmt.Println(gson.ToString(Union(map[int]int{1: 2, 2: 3, 3: 4}, map[int]int{3: 14, 4: 15, 5: 16})))                                          // {1:2, 2:3, 3:14, 4:15, 5:16}
fmt.Println(gson.ToString(Intersect(map[int]int{1: 2, 2: 3, 3: 4}, map[int]int{3: 14, 4: 15, 5: 16})))                                      // {3:14}
fmt.Println(gson.ToString(Diff(map[int]int{1: 2, 2: 3, 3: 4}, map[int]int{3: 14, 4: 15, 5: 16})))                                           // {1:2, 2:3}
fmt.Println(gson.ToString(UnionBy(gslice.Of(map[int]int{1: 2, 2: 3, 3: 4}, map[int]int{3: 14, 4: 15, 5: 16}), DiscardNew[int, int]())))     // {1:2, 2:3, 3:4, 4:15, 5:16}
fmt.Println(gson.ToString(IntersectBy(gslice.Of(map[int]int{1: 2, 2: 3, 3: 4}, map[int]int{3: 14, 4: 15, 5: 16}), DiscardNew[int, int]()))) // {3:4}
Output:

[1]
[2]
[1] [2]
[1 2 3]
[2 3 4]
[1 2 3] [2 3 4]
[1:2]
[1:2 2:3 3:4]
{"1":"2","2":"3","3":"4"}
{"2":3,"3":4}
true
true
false
2
2
[]
[2]
4
2
2 4
9
{"1":2,"2":3,"3":14,"4":15,"5":16}
{"3":14}
{"1":2,"2":3}
{"1":2,"2":3,"3":4,"4":15,"5":16}
{"3":4}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Avg

func Avg[K comparable, V constraints.Number](m map[K]V) float64

Avg returns the arithmetic mean of the values of map s.

🚀 EXAMPLE:

Avg(map[string]int{"1": 1, "2": 2, "3": 3}) ⏩ 2.0

💡 AKA: Mean, Average

func AvgBy

func AvgBy[K comparable, V any, N constraints.Number](m map[K]V, f func(V) N) float64

AvgBy applies function f to each values of map m, returns the arithmetic mean of function result.

💡 AKA: MeanBy, AverageBy

func Chunk

func Chunk[M ~map[K]V, K comparable, V any](m M, size int) []M

Chunk splits map into length-n chunks and returns chunks by a new slice.

The last chunk will be shorter if n does not evenly divide the length of the map.

⚠️ WARNING: The values in chunks will be in an indeterminate order.

func Clone

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

Clone returns a shallow copy of map. If the given map is nil, nil is returned.

🚀 EXAMPLE:

Clone(map[int]int{1: 1, 2: 2}) ⏩ map[int]int{1: 1, 2: 2}
Clone(map[int]int{})           ⏩ map[int]int{}
Clone[int, int](nil)           ⏩ nil

💡 HINT: Both keys and values are copied using assignment (=), so this is a shallow clone. If you want to do a deep clone, use CloneBy with an appropriate value clone function.

💡 AKA: Copy

func CloneBy

func CloneBy[M ~map[K]V, K comparable, V any](m M, f func(V) V) M

CloneBy is variant of Clone, it returns a copy of the map. Elements are copied using function f. If the given map is nil, nil is returned.

TODO: Example

💡 AKA: CopyBy

func Compact

func Compact[M ~map[K]V, K, V comparable](m M) M

Compact removes all zero values from given map m, returns a new map.

🚀 EXAMPLE:

m := map[int]string{0: "", 1: "foo", 2: "", 3: "bar"}
Compact(m) ⏩ map[int]string{1: "foo", 3: "bar"}

💡 HINT: See github.com/bytedance/gg/gvalue.Zero for details of zero value.

func Contains

func Contains[K comparable, V any](m map[K]V, k K) bool

Contains returns whether the key occur in map.

🚀 EXAMPLE:

m := map[int]string{1: ""}
Contains(m, 1)             ⏩ true
Contains(m, 0)             ⏩ false
var nilMap map[int]string
Contains(nilMap, 0)        ⏩ false

💡 HINT: See also ContainsAll, ContainsAny if you have multiple values to query.

func ContainsAll

func ContainsAll[K comparable, V any](m map[K]V, ks ...K) bool

ContainsAll returns whether all of given keys occur in map.

🚀 EXAMPLE:

m := map[int]string{1: "", 2: "",}
ContainsAll(m, 1, 2) ⏩ true
ContainsAll(m, 1, 3) ⏩ false
ContainsAll(m, 3)    ⏩ false

func ContainsAny

func ContainsAny[K comparable, V any](m map[K]V, ks ...K) bool

ContainsAny returns whether any of given keys occur in map.

🚀 EXAMPLE:

m := map[int]string{1: "", 2: ""}
ContainsAny(m, 1, 2) ⏩ true
ContainsAny(m, 1, 3) ⏩ true
ContainsAny(m, 3)    ⏩ false

func Count

func Count[K, V comparable](m map[K]V, v V) int

Count returns the times of value v that occur in map m.

🚀 EXAMPLE:

Count(map[int]string{1: "a", 2: "a", 3: "b"}, "a") ⏩ 2

💡 HINT:

  • Use CountValueBy if type of v is non-comparable
  • Use CountBy if you need to consider key when counting

func CountBy

func CountBy[K comparable, V any](m map[K]V, f func(K, V) bool) int

CountBy returns the times of pair (k, v) in map m that satisfy the predicate f.

🚀 EXAMPLE:

f := func (k int, v string) bool {
	i, _ := strconv.Atoi(v)
	return k%2 == 1 && i%2 == 1
}
CountBy(map[int]string{1: "1", 2: "2", 3: "3"}, f) ⏩ 0
CountBy(map[int]string{1: "1", 2: "2", 3: "4"}, f) ⏩ 1

func CountValueBy

func CountValueBy[K comparable, V any](m map[K]V, f func(V) bool) int

CountValueBy returns the times of value v in map m that satisfy the predicate f.

🚀 EXAMPLE:

f := func (v string) bool {
	i, _ := strconv.Atoi(v)
	return i%2 == 1
}
CountValueBy(map[int]string{1: "1", 2: "2", 3: "3"}, f) ⏩ 2
CountValueBy(map[int]string{1: "1", 2: "2", 3: "4"}, f) ⏩ 1

func Diff

func Diff[M ~map[K]V, K comparable, V any](m M, againsts ...M) M

Diff returns the difference of map m against other maps as a new map.

💡 NOTE: If the result is an empty set, always return an empty map instead of nil

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2}
Diff(m, nil)             ⏩ map[int]int{1: 1, 2: 2}
Diff(m, map[int]{1: 1})  ⏩ map[int]int{2: 2}
Diff(m, map[int]{3: 3})  ⏩ map[int]int{1: 1, 2: 2}

💡 HINT: Use github.com/bytedance/gg/collection/set.Set if you need a set data structure

TODO: Value type of againsts can be diff from m.

func Divide

func Divide[M ~map[K]V, K comparable, V any](m M, n int) []M

Divide splits map into exactly n slices and returns chunks by a new slice.

The length of chunks will be different if n does not evenly divide the length of the slice.

⚠️ WARNING: The values in chunks will be in an indeterminate order.

func Equal

func Equal[K, V comparable](m1, m2 map[K]V) bool

Equal reports whether two maps contain the same key/value pairs. values are compared using ==.

🚀 EXAMPLE:

Equal(map[int]int{1: 1, 2: 2}, map[int]int{1: 1, 2: 2}) ⏩ true
Equal(map[int]int{1: 1}, map[int]int{1: 1, 2: 2})       ⏩ false
Equal(map[int]int{}, map[int]int{})                     ⏩ true
Equal(map[int]int{}, nil)                               ⏩ true

func EqualBy

func EqualBy[K comparable, V any](m1, m2 map[K]V, eq func(v1, v2 V) bool) bool

EqualBy reports whether two maps contain the same key/value pairs. values are compared using function eq.

🚀 EXAMPLE:

eq := gvalue.Equal[int]
EqualBy(map[int]int{1: 1, 2: 2}, map[int]int{1: 1, 2: 2}, eq) ⏩ true
EqualBy(map[int]int{1: 1}, map[int]int{1: 1, 2: 2}, eq)       ⏩ false
EqualBy(map[int]int{}, map[int]int{}, eq)                     ⏩ true
EqualBy(map[int]int{}, nil, eq)                               ⏩ true

func Filter

func Filter[M ~map[K]V, K comparable, V any](m M, f func(K, V) bool) M

Filter applies predicate f to each key and value of map m, returns those keys and values that satisfy the predicate f as a new map.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2, 3: 2, 4: 3}
pred := func(k, v int) bool { return (k+v)%2 == 0 }
Filter(m, pred) ⏩ map[int]int{1: 1, 2: 2}

💡 HINT:

  • Use FilterKeys if you only need to filter the keys.
  • Use FilterValues if you only need to filter the values.
  • Use FilterMap if you also want to modify the keys/values during filtering.

func FilterByKeys

func FilterByKeys[M ~map[K]V, K comparable, V any](m M, keys ...K) M

FilterByKeys is a variant of Filter, filters map m by given keys slice, returns a new map containing only the key-value pairs where the key exists in the keys slice.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2, 3: 3, 4: 4}
keys := []int{1, 3, 5}
FilterByKeys(m, keys) ⏩ map[int]int{1: 1, 3: 3}

func FilterByValues

func FilterByValues[M ~map[K]V, K, V comparable](m M, values ...V) M

FilterByValues is a variant of Filter, filters map m by given values slice, returns a new map containing only the key-value pairs where the value exists in the values slice.

🚀 EXAMPLE:

m := map[int]int{1: 10, 2: 20, 3: 10, 4: 30}
values := []int{10, 30}
FilterByValues(m, values) ⏩ map[int]int{1: 10, 3: 10, 4: 30}

func FilterKeys

func FilterKeys[M ~map[K]V, K comparable, V any](m M, f func(K) bool) M

FilterKeys is a variant of Filter, applies predicate f to each key of map m, returns keys that satisfy the predicate f and the corresponding values as a new map.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2, 3: 2, 4: 3}
pred := func(k int) bool { return k%2 == 0 }
FilterKeys(m, pred) ⏩ map[int]int{2: 2, 4: 3}

func FilterMap

func FilterMap[K1, K2 comparable, V1, V2 any](m map[K1]V1, f func(K1, V1) (K2, V2, bool)) map[K2]V2

FilterMap does Filter and Map at the same time, applies function f to each key and value of map m. f returns (K2, V2, bool):

  • If true ,the returned key and value will added to the result map[K2]V2.
  • If false, the returned key and value will be dropped.

🚀 EXAMPLE:

f := func(k, v int) (string, string, bool) { return strconv.Itoa(k), strconv.Itoa(v), k != 0 && v != 0 }
FilterMap(map[int]int{1: 1, 2: 0, 0: 3}, f) ⏩ map[string]string{"1": "1"}

func FilterMapKeys

func FilterMapKeys[K1, K2 comparable, V any](m map[K1]V, f func(K1) (K2, bool)) map[K2]V

FilterMapKeys is a variant of FilterMap.

🚀 EXAMPLE:

f := func(v int) (string, bool) { return strconv.Itoa(v), v != 0 }
FilterMapKeys(map[int]int{1: 1, 2: 0, 0: 3}, f) ⏩ map[string]int{"1": 1, "2": 0}

func FilterMapValues

func FilterMapValues[K comparable, V1, V2 any](m map[K]V1, f func(V1) (V2, bool)) map[K]V2

FilterMapValues is a variant of FilterMap.

🚀 EXAMPLE:

f := func(v int) (string, bool) { return strconv.Itoa(v), v != 0 }
FilterMapValues(map[int]int{1: 1, 2: 0, 0: 3}, f) ⏩ map[int]string{1: "1", 0: "3"}

func FilterValues

func FilterValues[M ~map[K]V, K comparable, V any](m M, f func(V) bool) M

FilterValues is a variant of Filter, applies predicate f to each value of map m, returns values that satisfy the predicate f and the corresponding keys as a new map.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2, 3: 2, 4: 3}
pred := func(v int) bool { return v%2 == 0 }
FilterValues(m, pred) ⏩ map[int]int{2: 2, 3: 2}

func Indirect

func Indirect[K comparable, V any](m map[K]*V) map[K]V

Indirect returns the values pointed to by the pointers. If the pointer is nil, filter it out of the returned map.

🚀 EXAMPLE:

	v1, v2 := "1", "2"
 m := map[int]*string{ 1: &v1, 2: &v2, 3: nil}
 Indirect(m) ⏩ map[int]string{1: "1", 2: "2"}

💡 HINT: If you want to replace nil pointer with default value, use IndirectOr.

func IndirectOr

func IndirectOr[K comparable, V any](m map[K]*V, fallback V) map[K]V

IndirectOr is variant of Indirect. If the pointer is nil, returns the fallback value instead.

🚀 EXAMPLE:

	v1, v2 := "1", "2"
 m := map[int]*string{ 1: &v1, 2: &v2, 3: nil}
 IndirectOr(m, "nil") ⏩ map[int]string{1: "1", 2: "2", 3: "nil"}

func Intersect

func Intersect[M ~map[K]V, K comparable, V any](ms ...M) M

Intersect returns the intersection of maps as a new map.

💡 NOTE:

  • Once the key conflicts, the newer one will replace the older one (DiscardOld), use IntersectBy and ConflictFunc to customize conflict resolution.
  • If the result is an empty set, always return an empty map instead of nil

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2}
Intersect(m, nil)             ⏩ map[int]int{}
Intersect(m, map[int]{3: 3})  ⏩ map[int]int{}
Intersect(m, map[int]{1: 1})  ⏩ map[int]int{1: 1}
Intersect(m, map[int]{1: -1}) ⏩ map[int]int{1: -1} // "1:1" is replaced by the newer "1:-1"

💡 HINT: Use github.com/bytedance/gg/collection/set.Set if you need a set data structure

func IntersectBy

func IntersectBy[M ~map[K]V, K comparable, V any](ms []M, onConflict ConflictFunc[K, V]) M

IntersectBy returns the intersection of maps as a new map, conflicts are resolved by a custom ConflictFunc.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2}
Intersect(m, map[int]{1: -1})                                     ⏩ map[int]int{1: -1} // "1:1" is replaced by the newer "1:-1"
IntersectBy(gslice.Of(m, map[int]{1: -1}), DiscardOld[int,int]()) ⏩ map[int]int{1: -1} // same as above
IntersectBy(gslice.Of(m, map[int]{1: -1}), DiscardNew[int,int]()) ⏩ map[int]int{1: 1} // "1:1" is kept because it is older

For more examples, see ConflictFunc.

func Invert

func Invert[K, V comparable](m map[K]V) map[V]K

Invert inverts the keys and values of map, and returns a new map. (map[K]V] → map[V]K).

⚠️ WARNING: The iteration of the map is in an indeterminate order, for multiple KV-pairs with the same V, the K retained after inversion is UNSTABLE. If the length of the returned map is equal to the length of the given map, there are no key conflicts. Use InvertBy and ConflictFunc to customize conflict resolution. Use InvertGroup to avoid key loss when multiple keys mapped to the same value.

🚀 EXAMPLE:

Invert(map[string]int{"1": 1, "2": 2}) ⏩ map[int]string{1: "1", 2: "2"},
Invert(map[string]int{"1": 1, "2": 1}) ⏩ ⚠️ UNSTABLE: map[int]string{1: "1"} or map[int]string{1: "2"}

💡 AKA: Reverse

func InvertBy

func InvertBy[K, V comparable](m map[K]V, onConflict ConflictFunc[V, K]) map[V]K

InvertBy inverts the keys and values of map, and returns a new map. (map[K]V] → map[V]K), conflicts are resolved by a custom ConflictFunc.

💡 NOTE: the "oldVal", and "newVal" naming of ConflictFunc are meaningless because of the map's indeterminate iteration order. Further, DiscardOld and DiscardNew are also meaningless.

🚀 EXAMPLE:

InvertBy(map[string]int{"1": 1, "": 1}, DiscardZero(nil) ⏩ map[int]string{1: "1"},

func InvertGroup

func InvertGroup[K, V comparable](m map[K]V) map[V][]K

InvertGroup inverts the map by grouping keys that mapped to the same value into a slice. (map[K]V] → map[V][]K).

⚠️ WARNING: The iteration of the map is in an indeterminate order, for multiple KV-pairs with the same V, the order of K in the slice is UNSTABLE.

🚀 EXAMPLE:

InvertGroup(map[string]int{"1": 1, "2": 2}) ⏩ map[int][]string{1: {"1"}, 2: {"2"}},
InvertGroup(map[string]int{"1": 1, "2": 1}) ⏩ ⚠️ UNSTABLE: map[int][]string{1: {"1", "2"}} or map[int]string{1: {"2", "1"}}

func Items

func Items[K comparable, V any](m map[K]V) tuple.S2[K, V]

Items returns both the keys and values of the map m.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3"}
Items(m)          ⏩ []tuple.S2{{2, "2"}, {1, "1"}, {3, "3"}} // ⚠️INDETERMINATE ORDER⚠️
Items(m).Values() ⏩ []int{2, 1, 3}, []string{"2", "1", "3"}  // ⚠️INDETERMINATE ORDER⚠️

⚠️ WARNING: The returned items will be in an indeterminate order, use OrderedItems to get them in fixed order.

💡 HINT: The keys and values are returned in the form of a slice of tuples, and the keys slice values slice can be obtained separately through the github.com/bytedance/gg/collection/tuple.S2.Values method.

💡 AKA: KeyValues, KeyAndValues

func Keys

func Keys[K comparable, V any](m map[K]V) []K

Keys returns the keys of the map m.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3", 4: "4"}
Keys(m) ⏩ []int{1, 3, 2, 4} //⚠️INDETERMINATE ORDER⚠️

⚠️ WARNING: The keys will be in an indeterminate order, use OrderedKeys to get them in fixed order.

💡 HINT: If you want to merge key and value to single element, use ToSlice.

func Len

func Len[K comparable, V any](m map[K]V) int

Len returns the length of map m.

💡 HINT: This function is designed for high-order function, because the builtin function can not be used as function pointer. For example, if you want to get the total length of a 2D slice:

var s []map[int]int
total1 := SumBy(s, len)          // ❌ERROR❌ len (built-in) must be called
total2 := SumBy(s, Len[int,int]) // OK

func Load

func Load[K comparable, V any](m map[K]V, k K) goption.O[V]

Load returns the value stored in the map for a key.

If the value was not found in the map. goption.Nil[V]() is returned.

If the given map is nil, goption.Nil[V]() is returned.

💡 HINT: See also LoadAny, LoadAll, LoadSome if you have multiple values to load.

💡 AKA: Get

func LoadAll

func LoadAll[K comparable, V any](m map[K]V, ks ...K) []V

LoadAll returns the all value stored in the map for given keys.

If not all keys are not found in the map, nil is returned. Otherwise, the length of returned values should equal the length of given keys.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3"}
LoadAll(m, 1, 2) ⏩ []string{"1", "2"}
LoadAll(m, 1, 4) ⏩ []

func LoadAndDelete

func LoadAndDelete[K comparable, V any](m map[K]V, k K) goption.O[V]

LoadAndDelete deletes the value for a key, returning the previous value if any.

🚀 EXAMPLE:

var m = map[string]int { "foo": 1 }
LoadAndDelete(m, "bar") ⏩ goption.Nil()
LoadAndDelete(m, "foo") ⏩ goption.OK(1)
LoadAndDelete(m, "foo") ⏩ goption.Nil()

💡 HINT: If you want to delete an element "randomly", use Pop.

func LoadAny

func LoadAny[K comparable, V any](m map[K]V, ks ...K) (r goption.O[V])

LoadAny returns the all value stored in the map for given keys.

If no value is found in the map, goption.Nil[V]() is returned. Otherwise, the first found value is returned.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3"}
LoadAny(m, 1, 2) ⏩ goption.OK("1")
LoadAny(m, 5, 1) ⏩ goption.OK("1")
LoadAny(m, 5, 6) ⏩ goption.Nil[string]()

func LoadBy

func LoadBy[K comparable, V any](m map[K]V, f func(K, V) bool) goption.O[V]

LoadBy find the first value that satisfy the predicate f.

💡 NOTE: LoadBy has O(N) time complexity.

💡 AKA: FindBy, FindValueBy, GetBy, GetValueBy

func LoadItemBy

func LoadItemBy[K comparable, V any](m map[K]V, f func(K, V) bool) goption.O[tuple.T2[K, V]]

LoadItemBy find the first key-value pair that satisfy the predicate f.

💡 NOTE: LoadItemBy has O(N) time complexity.

💡 AKA: FindItemBy, GetItemBy

func LoadKey

func LoadKey[K, V comparable](m map[K]V, v V) goption.O[K]

LoadKey find the first key that mapped to the specified value.

💡 NOTE: LoadKey has O(N) time complexity.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3", 4: "4"}
LoadKey(m, "1") ⏩ goption.OK(1)
LoadKey(m, "a") ⏩ goption.Nil[int]()

💡 AKA: FindKey, FindByKey, GetKey, GetByKey

func LoadKeyBy

func LoadKeyBy[K comparable, V any](m map[K]V, f func(K, V) bool) goption.O[K]

LoadKeyBy find the first key that satisfy the predicate f.

💡 NOTE: LoadKeyBy has O(N) time complexity.

💡 AKA: FindKeyBy, GetKeyBy

func LoadOrStore

func LoadOrStore[K comparable, V any](m map[K]V, k K, defaultV V) (v V, loaded bool)

LoadOrStore returns the existing value for the key if present. Otherwise, it stores and returns the given value.

The loaded result is true if the value was loaded, false if stored.

⚠️ WARNING: LoadOrStore panics when a nil map is given.

💡 AKA: setdefault

func LoadOrStoreLazy

func LoadOrStoreLazy[K comparable, V any](m map[K]V, k K, f func() V) (v V, loaded bool)

LoadOrStoreLazy returns the existing value for the key if present. Otherwise, it stores and returns the value that lazy computed by function f.

The loaded result is true if the value was loaded, false if stored.

⚠️ WARNING: LoadOrStoreLazy panics when a nil map is given.

func LoadSome

func LoadSome[K comparable, V any](m map[K]V, ks ...K) []V

LoadSome returns the some values stored in the map for given keys.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3"}
LoadSome(m, 1, 2) ⏩ []string{"1", "2"}
LoadSome(m, 1, 4) ⏩ []string{"1"}

func Map

func Map[K1, K2 comparable, V1, V2 any](m map[K1]V1, f func(K1, V1) (K2, V2)) map[K2]V2

Map applies function f to each key and value of map m. Results of f are returned as a new map.

🚀 EXAMPLE:

f := func(k, v int) (string, string) { return strconv.Itoa(k), strconv.Itoa(v) }
Map(map[int]int{1: 1}, f) ⏩ map[string]string{"1": "1"}
Map(map[int]int{}, f)     ⏩ map[string]string{}

💡 HINT:

  • Use MapKeys if you only need to map the keys.
  • Use MapValues if you only need to map the values.
  • Use FilterMap if you also want to ignore keys/values during mapping.
  • Use ToSlice if you want to "map" both key and value to single element
  • Use TryMap if function f may fail (returns (K2, V2, error))

func MapKeys

func MapKeys[K1, K2 comparable, V any](m map[K1]V, f func(K1) K2) map[K2]V

MapKeys is a variant of Map, applies function f to each key of map m. Results of f and the corresponding values are returned as a new map.

🚀 EXAMPLE:

MapKeys(map[int]int{1: 1}, strconv.Itoa) ⏩ map[string]int{"1": 1}
MapKeys(map[int]int{}, strconv.Itoa)     ⏩ map[string]int{}

func MapValues

func MapValues[K comparable, V1, V2 any](m map[K]V1, f func(V1) V2) map[K]V2

MapValues is a variant of Map, applies function f to each values of map m. Results of f and the corresponding keys are returned as a new map.

🚀 EXAMPLE:

MapValues(map[int]int{1: 1}, strconv.Itoa) ⏩ map[int]string{1: "1"}
MapValues(map[int]int{}, strconv.Itoa)     ⏩ map[int]string{}

func Max

func Max[K comparable, V constraints.Ordered](m map[K]V) goption.O[V]

Max returns the maximum value of map m.

🚀 EXAMPLE:

Max(map[string]int{"1": 1, "2": 2, "3": 3}) ⏩ goption.OK(3)

💡 NOTE: If the given map is empty, goption.Nil[T]() is returned.

func MaxBy

func MaxBy[K comparable, V any](m map[K]V, less func(V, V) bool) goption.O[V]

MaxBy returns the maximum value of map m determined by function less.

🚀 EXAMPLE:

type Foo struct { Value int }
less := func(x, y Foo) bool { return x.Value < y.Value }
MaxBy(map[string]Foo{"1": {1}, "2": {2}, "3": {3}}, less) ⏩ goption.OK(Foo{3})

💡 NOTE: If the given map is empty, goption.Nil[V]() is returned.

func Merge

func Merge[M ~map[K]V, K comparable, V any](ms ...M) M

Merge is alias of Union.

func Min

func Min[K comparable, V constraints.Ordered](m map[K]V) goption.O[V]

Min returns the minimum element of map m.

🚀 EXAMPLE:

Min(map[string]int{"1": 1, "2": 2, "3": 3}) ⏩ goption.OK(1)

💡 NOTE: If the given map is empty, goption.Nil[V]() is returned.

func MinBy

func MinBy[K comparable, V any](m map[K]V, less func(V, V) bool) goption.O[V]

MinBy returns the minimum value of map m determined by function less.

🚀 EXAMPLE:

type Foo struct { Value int }
less := func(x, y Foo) bool { return x.Value < y.Value }
MinBy(map[string]Foo{"1": {1}, "2": {2}, "3": {3}}, less) ⏩ goption.OK(Foo{1})

💡 NOTE: If the given map is empty, goption.Nil[V]() is returned.

func MinMax

func MinMax[K comparable, V constraints.Ordered](m map[K]V) goption.O[tuple.T2[V, V]]

MinMax returns both minimum and maximum elements of map m. If the given map is empty, goption.Nil[tuple.T2[V,V]]() is returned.

MinMax(map[string]int{"1": 1, "2": 2, "3": 3}) ⏩ goption.OK(tuple.T2{1, 3})

💡 AKA: Bound

func MinMaxBy

func MinMaxBy[K comparable, V any](m map[K]V, less func(V, V) bool) goption.O[tuple.T2[V, V]]

MinMaxBy returns both minimum and maximum elements of map m determined by function less. If the given map is empty, goption.Nil[tuple.T2[V,V]]() is returned.

🚀 EXAMPLE:

type Foo struct { Value int }
less := func(x, y Foo) bool { return x.Value < y.Value }
m := map[string]Foo{"1": {1}, "2": {2}, "3": {3}}
MinMaxBy(m, less) ⏩ goption.OK(tuple.T2{Foo{1}, Foo{3}})

💡 AKA: BoundBy

func OrderedItems

func OrderedItems[K constraints.Ordered, V any](m map[K]V) tuple.S2[K, V]

OrderedItems is variant of Items, returns the keys and values of the map m in fixed order.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3"}
OrderedItems(m)          ⏩ []tuple.S2{{1, "1"}, {2, "2"}, {3, "3"}}
OrderedItems(m).Values() ⏩ []int{1, 2, 3}, []string{"1", "2", "3"}

💡 HINT: The keys and values are returned in the form of a slice of tuples, and the keys slice values slice can be obtained separately through the github.com/bytedance/gg/collection/tuple.S2.Values method.

💡 AKA: SortedItems, SortedKeyValues, SortedKeyAndValues

func OrderedKeys

func OrderedKeys[K constraints.Ordered, V any](m map[K]V) []K

OrderedKeys is the variant of Keys, returns the keys of the map m in fixed order.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3", 4: "4"}
OrderedKeys(m) ⏩ []int{1, 2, 3, 4}

💡 HINT: If you want to merge key and value to single element, use ToOrderedSlice.

💡 AKA: SortedKey

func OrderedValues

func OrderedValues[K constraints.Ordered, V any](m map[K]V) []V

OrderedValues is variant of Values, returns the values of the map m in fixed order.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3", 4: "4"}
OrderedValues(m) ⏩ []string{"1", "2", "3", "4"}

💡 HINT: If you want to merge key and value to single element, use ToOrderedSlice.

💡 AKA: SortedValues

func Peek

func Peek[K comparable, V any](m map[K]V) goption.O[V]

Peek tries to load a "random" element from map m. If m is empty, goption.Nil[V]() is returned.

🚀 EXAMPLE:

var m = map[string]int { "foo": 1 }
Peek(m) ⏩ goption.OK(1)
var m2 = map[string]int {}
Peek(m2) ⏩ goption.Nil()

⚠️ WARNING: As map iteration is indeterminate ordered, we said it is "random".

💡 HINT:

  • If you want to delete the returned value, use Pop
  • If you also want to know the key of returned value, use PeekItem

func PeekItem

func PeekItem[K comparable, V any](m map[K]V) goption.O[tuple.T2[K, V]]

PeekItem is variant of Peek, return key-value pair instead of a single value.

func Pop

func Pop[K comparable, V any](m map[K]V) goption.O[V]

Pop tries to load and DELETE a "random" element from map m. If m is empty, goption.Nil[V]() is returned.

🚀 EXAMPLE:

var m = map[string]int { "foo": 1 }
Pop(m) ⏩ goption.OK(1)
Pop(m) ⏩ goption.Nil()

⚠️ WARNING: As map iteration is indeterminate ordered, we said it is "random".

💡 HINT:

  • If you don't want to delete the element, use Peek
  • If you want to delete element by key, use LoadAndDelete
  • If you want to know the key of poped value, use PopItem

func PopItem

func PopItem[K comparable, V any](m map[K]V) goption.O[tuple.T2[K, V]]

PopItem is variant of Pop, return key-value pair instead of a single value.

func PtrOf

func PtrOf[K comparable, V any](m map[K]V) map[K]*V

PtrOf returns pointers that point to equivalent values of map m. (map[K]V → map[K]*V).

🚀 EXAMPLE:

PtrOf(map[int]string{1: "1", 2: "2"}) ⏩ map[int]*string{1: (*string)("1"), 2: (*string)("2")}

⚠️ WARNING: The returned pointers do not point to values of the original map, user CAN NOT modify the value by modifying the pointer.

func Reject

func Reject[M ~map[K]V, K comparable, V any](m M, f func(K, V) bool) M

Reject applies predicate f to each key and value of map m, returns those keys and values that do not satisfy the predicate f as a new map.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2, 3: 2, 4: 3}
pred := func(k, v int) bool { return (k+v)%2 != 0 }
Reject(m, pred) ⏩ map[int]int{1: 1, 2: 2}

💡 HINT:

func RejectByKeys

func RejectByKeys[M ~map[K]V, K comparable, V any](m M, keys ...K) M

RejectByKeys is the opposite of FilterByKeys, removes entries from map m where the key exists in the keys slice, returns a new map containing only the key-value pairs where the key does not exist in the keys slice.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2, 3: 3, 4: 4}
keys := []int{1, 3}
RejectByKeys(m, keys) ⏩ map[int]int{2: 2, 4: 4}

func RejectByValues

func RejectByValues[M ~map[K]V, K, V comparable](m M, values ...V) M

RejectByValues is the opposite of FilterByValues, removes entries from map m where the value exists in the values slice, returns a new map containing only the key-value pairs where the value does not exist in the values slice.

🚀 EXAMPLE:

m := map[int]int{1: 10, 2: 20, 3: 10, 4: 30}
values := []int{10, 30}
RejectByValues(m, values) ⏩ map[int]int{2: 20}

func RejectKeys

func RejectKeys[M ~map[K]V, K comparable, V any](m M, f func(K) bool) M

RejectKeys applies predicate f to each key of map m, returns keys that do not satisfy the predicate f and the corresponding values as a new map.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2, 3: 2, 4: 3}
pred := func(k int) bool { return k%2 != 0 }
RejectKeys(m, pred) ⏩ map[int]int{2: 2, 4: 3}

func RejectValues

func RejectValues[M ~map[K]V, K comparable, V any](m M, f func(V) bool) M

RejectValues applies predicate f to each value of map m, returns values that do not satisfy the predicate f and the corresponding keys as a new map.

🚀 EXAMPLE:

 m := map[int]int{1: 1, 2: 2, 3: 2, 4: 3}
 pred := func(v int) bool { return v%2 != 0 }
	RejectValues(m, pred) ⏩ map[int]int{2: 2, 3: 2}

func Sum

func Sum[K comparable, V constraints.Number](m map[K]V) V

Sum returns the arithmetic sum of the values of map m.

🚀 EXAMPLE:

Sum(map[string]int{"1": 1, "2": 2, "3": 3}) ⏩ 6

💡 NOTE: The returned type is still T, it may overflow for smaller types (such as int8, uint8).

func SumBy

func SumBy[K comparable, V any, N constraints.Number](m map[K]V, f func(V) N) N

SumBy applies function f to each value of map m, returns the arithmetic sum of function result.

func ToOrderedSlice

func ToOrderedSlice[K constraints.Ordered, V, T any](m map[K]V, f func(K, V) T) []T

ToOrderedSlice is variant of ToSlice, the returned slice is in fixed order.

🚀 EXAMPLE:

f := func (k, v int) string {
	return fmt.Sprintf("%d: %d", k, v)
}
m := map[int]int{1: 1, 2: 2, 3: 3}
ToOrderedSlice(m, f) ⏩ []string{"1: 1", "2: 2", "3: 3"}

func ToSlice

func ToSlice[K comparable, V, T any](m map[K]V, f func(K, V) T) []T

ToSlice converts the map m to a slice by function f.

⚠️ WARNING: The returned slice will be in an indeterminate order, use ToOrderedSlice to get them in fixed order.

🚀 EXAMPLE:

f := func (k, v int) string {
	return fmt.Sprintf("%d: %d", k, v)
}
m := map[int]int{1: 1, 2: 2, 3: 3}
ToSlice(m, f) ⏩ []string{"1: 1", "3: 3", "2: 2"} //⚠️INDETERMINATE ORDER⚠️

💡 HINT:

func TryFilterMap

func TryFilterMap[K1, K2 comparable, V1, V2 any](m map[K1]V1, f func(K1, V1) (K2, V2, error)) map[K2]V2

TryFilterMap is a variant of FilterMap that allows function f to fail (return error).

🚀 EXAMPLE:

f := func(k, v int) (string, string, error) {
	ki, kerr := strconv.Atoi(k)
	vi, verr := strconv.Atoi(v)
	return ki, vi, errors.Join(kerr, verr)
}
TryFilterMap(map[string]string{"1": "1", "2": "2"}, f) ⏩ map[int]int{1: 1, 2: 2}
TryFilterMap(map[string]string{"1": "a", "2": "2"}, f) ⏩ map[int]int{2: 2})

func TryFilterMapKeys

func TryFilterMapKeys[K1, K2 comparable, V any](m map[K1]V, f func(K1) (K2, error)) map[K2]V

TryFilterMapKeys is a variant of FilterMapKeys that allows function f to fail (return error).

🚀 EXAMPLE:

FilterMapKeys(map[string]string{"1": "1", "2": "2"}, strconv.Atoi) ⏩ map[int]string{1: "1", 2: "2"}
FilterMapKeys(map[string]string{"1": "1", "a": "2"}, strconv.Atoi) ⏩ map[int]string{1: "1"}

func TryFilterMapValues

func TryFilterMapValues[K comparable, V1, V2 any](m map[K]V1, f func(V1) (V2, error)) map[K]V2

TryFilterMapValues is a variant of FilterMapValues that allows function f to fail (return error).

🚀 EXAMPLE:

FilterMapValues(map[string]string{"1": "1", "2": "2"}, strconv.Atoi) ⏩ map[string]int{"1": 1, "2": 2}
FilterMapValues(map[string]string{"1": "1", "2": "a"}, strconv.Atoi) ⏩ map[string]int{"1": 1}

func TryMap

func TryMap[K1, K2 comparable, V1, V2 any](m map[K1]V1, f func(K1, V1) (K2, V2, error)) gresult.R[map[K2]V2]

TryMap is a variant of Map that allows function f to fail (return error).

🚀 EXAMPLE:

f := func(k, v int) (string, string, error) {
	ki, kerr := strconv.Atoi(k)
	vi, verr := strconv.Atoi(v)
	return ki, vi, errors.Join(kerr, verr)
}
TryMap(map[string]string{"1": "1"}, f) ⏩ gresult.OK(map[int]int{1: 1})
TryMap(map[string]string{"1": "a"}, f) ⏩ gresult.Err("strconv.Atoi: parsing \"a\": invalid syntax")

💡 HINT:

func TryMapKeys

func TryMapKeys[K1, K2 comparable, V any](m map[K1]V, f func(K1) (K2, error)) gresult.R[map[K2]V]

TryMapKeys is a variant of MapKeys that allows function f to fail (return error).

🚀 EXAMPLE:

TryMapKeys(map[string]string{"1": "1"}, strconv.Atoi) ⏩ gresult.OK(map[int]string{1: "1"})
TryMapKeys(map[string]string{"a": "1"}, strconv.Atoi) ⏩ gresult.Err("strconv.Atoi: parsing \"a\": invalid syntax")
TryMapKeys(map[string]string{}, strconv.Itoa)         ⏩ gresult.OK(map[int]string{})

func TryMapValues

func TryMapValues[K comparable, V1, V2 any](m map[K]V1, f func(V1) (V2, error)) gresult.R[map[K]V2]

TryMapValues is a variant of MapValues that allows function f to fail (return error).

🚀 EXAMPLE:

TryMapValues(map[string]string{"1": "1"}, strconv.Atoi) ⏩ gresult.OK(map[string]int{"1": 1})
TryMapValues(map[string]string{"1": "a"}, strconv.Atoi) ⏩ gresult.Err("strconv.Atoi: parsing \"a\": invalid syntax")
TryMapValues(map[string]string{}, strconv.Itoa)         ⏩ gresult.OK(map[string]int{})

func TypeAssert

func TypeAssert[To any, K comparable, From any](m map[K]From) map[K]To

TypeAssert converts values of map from type From to type To by type assertion.

🚀 EXAMPLE:

TypeAssert[int](map[int]any{1: 1, 2: 2})   ⏩ map[int]int{1: 1, 2: 2}
TypeAssert[any](map[int]int{1: 1, 2: 2})   ⏩ map[int]any{1: 1, 2: 2}
TypeAssert[int64](map[int]int{1: 1, 2: 2}) ⏩ ❌PANIC❌

⚠️ WARNING:

func Union

func Union[M ~map[K]V, K comparable, V any](ms ...M) M

Union returns the unions of maps as a new map.

💡 NOTE:

  • Once the key conflicts, the newer value always replace the older one (DiscardOld), use UnionBy and ConflictFunc to customize conflict resolution.
  • If the result is an empty set, always return an empty map instead of nil

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2}
Union(m, nil)             ⏩ map[int]int{1: 1, 2: 2}
Union(m, map[int]{3: 3})  ⏩ map[int]int{1: 1, 2: 2, 3: 3}
Union(m, map[int]{2: -1}) ⏩ map[int]int{1: 1, 2: -1} // "2:2" is replaced by the newer "2:-1"

💡 HINT: Use github.com/bytedance/gg/collection/set.Set if you need a set data structure

💡 AKA: Merge, Concat, Combine

func UnionBy

func UnionBy[M ~map[K]V, K comparable, V any](ms []M, onConflict ConflictFunc[K, V]) M

UnionBy returns the unions of maps as a new map, conflicts are resolved by a custom ConflictFunc.

🚀 EXAMPLE:

m := map[int]int{1: 1, 2: 2}
Union(m, map[int]{2: 0})                               ⏩ map[int]int{1: 1, 2: 0} // "2:2" is replaced by the newer "2:0"
UnionBy(gslice.Of(m, map[int]int{2: 0}), DiscardOld()) ⏩ map[int]int{1: 1, 2: 0} // same as above
UnionBy(gslice.Of(m, map[int]int{2: 0}), DiscardNew()) ⏩ map[int]int{1: 1, 2: 2} // "2:2" is kept because it is older

For more examples, see ConflictFunc.

func Values

func Values[K comparable, V any](m map[K]V) []V

Values returns the values of the map m.

🚀 EXAMPLE:

m := map[int]string{1: "1", 2: "2", 3: "3", 4: "4"}
Values(m) ⏩ []string{"1", "4", "2", "3"} //⚠️INDETERMINATE ORDER⚠️

⚠️ WARNING: The keys values be in an indeterminate order, use OrderedValues to get them in fixed order.

💡 HINT: If you want to merge key and value to single element, use ToSlice.

Types

type ConflictFunc

type ConflictFunc[K comparable, V any] func(key K, oldVal, newVal V) V

ConflictFunc is used to merge the conflicting key-value of map operations.

Once the key conflicts, the conflicting key and the corresponding values will be passed to this function, and the user can resolve the conflict by returning a new value. Here are some pre-defined ConflictFuncs:

🚀 EXAMPLE:

Union(
	map[int]int{1: 1, 2: 2},
	map[int]int{      2: 0})        ⏩ map[int]int{1: 1, 2: 0} // "2:2" is replaced by the newer "2:0"

UnionBy(
	gslice.Of(,
		map[int]int{1: 1, 2: 2},
		map[int]int{      2: 0}),
	DiscardOld())                   ⏩ map[int]int{1: 1, 2: 0} // same as above, DiscardOld is the default behavior

UnionBy(
	gslice.Of(,
		map[int]int{1: 1, 2: 2},
		map[int]int{      2: 0}),
	DiscardNew())                   ⏩ map[int]int{1: 1, 2: 2} // "2:2" is kept because the newer is always discarded

UnionBy(
	gslice.Of(,
		map[int]int{      2: 0},
		map[int]int{1: 1, 2: 1},
		map[int]int{1: 1, 2: 2},
		map[int]int{      2: 0}),
	DiscardZero(nil))               ⏩ map[int]int{1: 1, 2: 2} // "2:2" is kept because 2 is the newest non-zero value

UnionBy(
	gslice.Of(,
		map[int]int{      2: 0},
		map[int]int{1: 1, 2: 1},
		map[int]int{1: 1, 2: 2},
		map[int]int{      2: 0}),
	DiscardZero(DiscardNew()))      ⏩ map[int]int{1: 1, 2: 1} // "2:1" is kept because 1 is the oldest non-zero value

func DiscardNew

func DiscardNew[K comparable, V any]() ConflictFunc[K, V]

DiscardNew returns a ConflictFunc that always return the older value.

func DiscardNil

func DiscardNil[K comparable, V comparable](fallback ConflictFunc[K, *V]) ConflictFunc[K, *V]

DiscardNil returns a ConflictFunc that always return the non-zero value.

💡 NOTE: If both values are non-nil, the fallback function will be called. If the fallback function is nil, DiscardOld will be called.

func DiscardOld

func DiscardOld[K comparable, V any]() ConflictFunc[K, V]

DiscardOld returns a ConflictFunc that always return the newer value.

func DiscardZero

func DiscardZero[K comparable, V comparable](fallback ConflictFunc[K, V]) ConflictFunc[K, V]

DiscardZero returns a ConflictFunc that always return the non-zero value.

💡 NOTE: If both values are non-zero, the fallback function will be called. If the fallback function is nil, DiscardOld will be called.

💡 HINT: See github.com/bytedance/gg/gvalue.Zero for details of zero value.

Jump to

Keyboard shortcuts

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