goutils/maputils/mapUtils.go
2024-12-02 08:42:42 +01:00

85 lines
2.3 KiB
Go

package maputils
import "git.mstar.dev/mstar/goutils/sliceutils"
// MapSameKeys applies a given function to every key-value pair of a map.
// The returned map's value type may be different from the type of the inital map's value
// But it will keep the same keys as the input map
func MapSameKeys[K comparable, V any, R any](dic map[K]V, apply func(K, V) R) map[K]R {
n := make(map[K]R, len(dic))
for key, val := range dic {
n[key] = apply(key, val)
}
return n
}
// MapNewKeys applies a given function to every key-value pair of a map.
// The returned map's keys and values may be of different types as the input map
// The first return value of the apply func will be used as new key, the second as the value
func MapNewKeys[Kin comparable, Vin any, Kout comparable, Vout any](
in map[Kin]Vin,
apply func(Kin, Vin) (Kout, Vout),
) map[Kout]Vout {
n := make(map[Kout]Vout, len(in))
for ki, vi := range in {
ko, vo := apply(ki, vi)
n[ko] = vo
}
return n
}
// FilterMap filters a map using a given function.
// If the filter function returns true, the key-value pair stays, otherwise it gets removed.
func FilterMap[K comparable, V any](dic map[K]V, filter func(K, V) bool) map[K]V {
n := make(map[K]V, 0)
for key, val := range dic {
if filter(key, val) {
n[key] = val
}
}
return n
}
// KeysFromMap creates a slice of keys that match the keys in a given map.
func KeysFromMap[K comparable, V any](m map[K]V) []K {
keys := make([]K, len(m))
i := 0
for k := range m {
keys[i] = k
i++
}
return keys
}
// CompareMap compares two maps for key-val equality (If both maps have the same key-value pairs).
func CompareMap[K, V comparable](a, b map[K]V) bool {
if len(a) != len(b) {
return false
}
// Check if both maps have the same keys
if !sliceutils.CompareUnordered(KeysFromMap(a), KeysFromMap(b)) {
return false
}
// Then compare key-value pairs
for k, v := range a {
val, ok := b[k]
if !(ok && val == v) {
return false
}
}
return true
}
func Compact[K comparable, V any](
m map[K]V,
compactor func(accK K, accV V, nextK K, nextV V) (K, V),
) (K, V) {
var accK K
var accV V
for k, v := range m {
accK, accV = compactor(accK, accV, k, v)
}
return accK, accV
}