wp-go/helper/maps/map.go

205 lines
3.4 KiB
Go
Raw Normal View History

2023-01-21 11:31:23 +00:00
package maps
2023-01-14 13:12:26 +00:00
2023-02-07 15:46:34 +00:00
import (
"encoding/json"
2023-03-12 12:28:57 +00:00
"github.com/fthvgb1/wp-go/helper"
2023-02-07 15:46:34 +00:00
)
2023-01-14 13:12:26 +00:00
2023-01-17 15:18:31 +00:00
func StrAnyMapToStruct[T any, M any](m M) (r T, err error) {
2023-01-14 13:12:26 +00:00
str, err := json.Marshal(m)
if err != nil {
return
}
err = json.Unmarshal(str, &r)
return
}
2023-01-17 15:18:31 +00:00
func StructToAnyMap[K comparable, T any](s T) (r map[K]any, err error) {
2023-01-14 13:12:26 +00:00
marshal, err := json.Marshal(s)
if err != nil {
return
}
2023-01-17 15:18:31 +00:00
r = make(map[K]any)
2023-01-14 13:12:26 +00:00
err = json.Unmarshal(marshal, &r)
return
}
func Filter[M ~map[K]V, K comparable, V any](fn func(K, V) bool, m ...M) M {
var r = map[K]V{}
for _, mm := range m {
for k, v := range mm {
if ok := fn(k, v); ok {
r[k] = v
}
}
}
return r
}
2023-01-21 11:31:23 +00:00
func FilterToSlice[T any, K comparable, V any](m map[K]V, fn func(K, V) (T, bool)) (r []T) {
2023-01-14 13:12:26 +00:00
for k, v := range m {
vv, ok := fn(k, v)
if ok {
r = append(r, vv)
}
}
return
}
2023-01-21 11:31:23 +00:00
// AnyAnyToStrAny map[any]any => map[string]any 方便json转换
func AnyAnyToStrAny(m map[any]any) (r map[string]any) {
r = make(map[string]any)
for k, v := range m {
kk, ok := k.(string)
if ok {
vv, ok := v.(map[any]any)
if ok {
2023-01-21 11:31:23 +00:00
r[kk] = AnyAnyToStrAny(vv)
} else {
r[kk] = v
}
}
}
return
}
2023-03-27 03:37:24 +00:00
func StrAnyToAnyAny(m map[string]any) (r map[any]any) {
r = make(map[any]any)
for kk, v := range m {
vv, ok := v.(map[string]any)
if ok {
r[kk] = StrAnyToAnyAny(vv)
} else {
r[kk] = v
}
}
return
}
2023-01-25 18:26:36 +00:00
func IsExists[K comparable, V any](m map[K]V, k K) bool {
_, ok := m[k]
return ok
}
2023-02-07 15:46:34 +00:00
func Keys[K comparable, V any](m map[K]V) []K {
return FilterToSlice(m, func(k K, v V) (K, bool) {
return k, true
})
}
func Values[K comparable, V any](m map[K]V) []V {
return FilterToSlice(m, func(k K, v V) (V, bool) {
return v, true
})
}
2023-01-25 18:26:36 +00:00
func Reduce[T, V any, K comparable](m map[K]V, fn func(K, V, T) T, r T) T {
for k, v := range m {
r = fn(k, v, r)
}
return r
}
2023-01-27 15:48:48 +00:00
func Replace[K comparable, V any](m map[K]V, mm ...map[K]V) map[K]V {
for _, n := range mm {
for k, v := range n {
_, ok := m[k]
if ok {
m[k] = v
}
}
}
return m
}
2023-02-09 15:15:10 +00:00
func Copy[K comparable, V any](m map[K]V) map[K]V {
r := make(map[K]V)
for k, v := range m {
r[k] = v
}
return r
}
func Merge[K comparable, V any](m ...map[K]V) map[K]V {
if len(m) < 1 {
2023-04-30 13:17:33 +00:00
return nil
2023-02-09 15:15:10 +00:00
} else if len(m) < 2 {
return m[0]
}
mm := m[0]
2023-04-30 13:17:33 +00:00
if mm == nil {
mm = make(map[K]V)
}
2023-02-09 15:15:10 +00:00
for _, m2 := range m[1:] {
for k, v := range m2 {
mm[k] = v
}
}
return mm
}
2023-02-15 16:32:02 +00:00
2023-04-30 13:17:33 +00:00
func MergeBy[K comparable, V any](fn func(k K, v1, v2 V) (V, bool), m ...map[K]V) map[K]V {
if len(m) < 1 {
return nil
} else if len(m) < 2 {
return m[0]
}
mm := m[0]
if mm == nil {
mm = make(map[K]V)
}
for _, m2 := range m[1:] {
for k, v := range m2 {
vv, ok := mm[k]
if ok {
vvv, ok := fn(k, vv, v)
if ok {
v = vvv
}
}
mm[k] = v
}
}
return mm
}
2023-03-12 12:28:57 +00:00
func FilterZeroMerge[K comparable, V any](m ...map[K]V) map[K]V {
if len(m) < 1 {
2023-05-01 05:34:23 +00:00
return nil
2023-03-12 12:28:57 +00:00
} else if len(m) < 2 {
return m[0]
}
mm := m[0]
2023-04-30 13:17:33 +00:00
if mm == nil {
mm = make(map[K]V)
}
2023-03-12 12:28:57 +00:00
for _, m2 := range m[1:] {
for k, v := range m2 {
if helper.IsZeros(v) {
continue
}
mm[k] = v
}
}
return mm
}
2023-02-15 16:32:02 +00:00
func WithDefaultVal[K comparable, V any](m map[K]V, k K, defaults V) V {
vv, ok := m[k]
if ok {
return vv
}
return defaults
}
2023-03-27 03:37:24 +00:00
func AnyAnyMapTo[K comparable, V any](m map[any]any, fn func(k, v any) (K, V, bool)) map[K]V {
mm := make(map[K]V)
2023-03-27 03:37:24 +00:00
for k, v := range m {
key, val, ok := fn(k, v)
if ok {
mm[key] = val
}
}
return mm
}