2023-01-21 11:31:23 +00:00
|
|
|
package maps
|
2023-01-11 05:56:56 +00:00
|
|
|
|
2023-07-04 15:36:25 +00:00
|
|
|
import (
|
|
|
|
"github.com/fthvgb1/wp-go/helper/slice"
|
|
|
|
"golang.org/x/exp/constraints"
|
|
|
|
"strings"
|
|
|
|
)
|
2023-01-11 05:56:56 +00:00
|
|
|
|
2023-06-29 16:06:26 +00:00
|
|
|
func GetStrAnyVal[T any](m map[string]any, key string, delimiter ...string) (r T, o bool) {
|
|
|
|
separator := "."
|
|
|
|
if len(delimiter) > 0 && delimiter[0] != "" {
|
|
|
|
separator = delimiter[0]
|
|
|
|
}
|
|
|
|
k := strings.Split(key, separator)
|
2023-01-11 05:56:56 +00:00
|
|
|
if len(k) > 1 {
|
2023-02-10 13:23:30 +00:00
|
|
|
val, ok := m[k[0]]
|
2023-01-11 05:56:56 +00:00
|
|
|
if ok {
|
|
|
|
vx, ok := val.(map[string]any)
|
|
|
|
if ok {
|
2023-06-29 16:06:26 +00:00
|
|
|
r, o = GetStrAnyVal[T](vx, strings.Join(k[1:], separator))
|
2023-01-11 05:56:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2023-02-10 13:23:30 +00:00
|
|
|
x, ok := m[k[0]]
|
2023-01-11 05:56:56 +00:00
|
|
|
if ok {
|
|
|
|
vv, ok := x.(T)
|
|
|
|
if ok {
|
|
|
|
o = true
|
|
|
|
r = vv
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2023-01-12 04:54:14 +00:00
|
|
|
|
2023-02-20 17:07:32 +00:00
|
|
|
func GetStrAnyValWithDefaults[T any](m map[string]any, key string, defaults T) (r T) {
|
|
|
|
r = defaults
|
|
|
|
v, ok := GetStrAnyVal[T](m, key)
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
r = v
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetStrMapAnyValWithAny 使用"." 分隔层级
|
2023-07-05 15:23:47 +00:00
|
|
|
func GetStrMapAnyValWithAny(v map[string]any, key string) (r any, o bool) {
|
2023-01-12 04:54:14 +00:00
|
|
|
k := strings.Split(key, ".")
|
|
|
|
if len(k) > 1 {
|
|
|
|
val, ok := v[k[0]]
|
|
|
|
if ok {
|
|
|
|
vx, ok := val.(map[string]any)
|
|
|
|
if ok {
|
2023-07-05 15:23:47 +00:00
|
|
|
r, o = GetStrMapAnyValWithAny(vx, strings.Join(k[1:], "."))
|
2023-01-12 04:54:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
x, ok := v[k[0]]
|
|
|
|
if ok {
|
|
|
|
o = true
|
|
|
|
r = x
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2023-03-06 12:53:51 +00:00
|
|
|
|
|
|
|
func GetAnyAnyMapVal[T any](m map[any]any, k ...any) (r T, o bool) {
|
|
|
|
if len(k) > 1 {
|
|
|
|
val, ok := m[k[0]]
|
|
|
|
if ok {
|
|
|
|
vx, ok := val.(map[any]any)
|
|
|
|
if ok {
|
|
|
|
r, o = GetAnyAnyMapVal[T](vx, k[1:]...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
x, ok := m[k[0]]
|
|
|
|
if ok {
|
|
|
|
vv, ok := x.(T)
|
|
|
|
if ok {
|
|
|
|
o = true
|
|
|
|
r = vv
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetAnyAnyMapWithAny(v map[any]any, k ...any) (r any, o bool) {
|
|
|
|
if len(k) > 1 {
|
|
|
|
val, ok := v[k[0]]
|
|
|
|
if ok {
|
|
|
|
vx, ok := val.(map[any]any)
|
|
|
|
if ok {
|
|
|
|
r, o = GetAnyAnyMapWithAny(vx, k[1:]...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
x, ok := v[k[0]]
|
|
|
|
if ok {
|
|
|
|
o = true
|
|
|
|
r = x
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetAnyAnyValWithDefaults[T any](m map[any]any, defaults T, key ...any) (r T) {
|
|
|
|
r = defaults
|
|
|
|
v, ok := GetAnyAnyMapVal[T](m, key...)
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
r = v
|
|
|
|
return
|
|
|
|
}
|
2023-06-28 14:49:45 +00:00
|
|
|
|
2023-07-04 15:36:25 +00:00
|
|
|
func SetStrAnyVal[T any](m map[string]any, k string, v T, delimiter ...string) {
|
2023-06-29 16:06:26 +00:00
|
|
|
del := "."
|
|
|
|
if len(delimiter) > 0 && delimiter[0] != "" {
|
|
|
|
del = delimiter[0]
|
|
|
|
}
|
|
|
|
kk := strings.Split(k, del)
|
2023-06-28 14:49:45 +00:00
|
|
|
if len(kk) < 1 {
|
|
|
|
return
|
|
|
|
} else if len(kk) < 2 {
|
|
|
|
m[k] = v
|
|
|
|
return
|
|
|
|
}
|
2023-06-29 16:06:26 +00:00
|
|
|
mm, ok := GetStrAnyVal[map[string]any](m, strings.Join(kk[0:len(kk)-1], del))
|
|
|
|
if ok {
|
|
|
|
mm[kk[len(kk)-1]] = v
|
|
|
|
return
|
|
|
|
}
|
|
|
|
mx, ok := GetStrAnyVal[map[string]any](m, kk[0])
|
|
|
|
if !ok {
|
|
|
|
m[kk[0]] = map[string]any{}
|
|
|
|
mx = m[kk[0]].(map[string]any)
|
|
|
|
}
|
|
|
|
for i, _ := range kk[0 : len(kk)-2] {
|
|
|
|
key := kk[i+1]
|
|
|
|
mm, ok := mx[key]
|
2023-06-28 14:49:45 +00:00
|
|
|
if !ok {
|
2023-06-29 16:06:26 +00:00
|
|
|
mmm := map[string]any{}
|
|
|
|
mx[key] = mmm
|
|
|
|
mx = mmm
|
|
|
|
|
|
|
|
} else {
|
|
|
|
mx = mm.(map[string]any)
|
2023-06-28 14:49:45 +00:00
|
|
|
}
|
|
|
|
}
|
2023-06-29 16:06:26 +00:00
|
|
|
mx[kk[len(kk)-1]] = v
|
2023-06-28 14:49:45 +00:00
|
|
|
}
|
2023-06-29 15:29:25 +00:00
|
|
|
|
2023-07-04 15:36:25 +00:00
|
|
|
func SetAnyAnyVal[T any](m map[any]any, v T, k ...any) {
|
2023-06-29 15:29:25 +00:00
|
|
|
if len(k) < 1 {
|
|
|
|
return
|
|
|
|
} else if len(k) == 1 {
|
|
|
|
m[k[0]] = v
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for i, _ := range k[0 : len(k)-1] {
|
|
|
|
key := k[0 : i+1]
|
|
|
|
mm, ok := GetAnyAnyMapVal[map[any]any](m, key...)
|
|
|
|
if !ok {
|
|
|
|
mm = map[any]any{}
|
|
|
|
preKey := k[0:i]
|
|
|
|
if len(preKey) == 0 {
|
2023-07-04 15:36:25 +00:00
|
|
|
SetAnyAnyVal(m, mm, key...)
|
2023-06-29 15:29:25 +00:00
|
|
|
} else {
|
|
|
|
m, _ := GetAnyAnyMapVal[map[any]any](m, preKey...)
|
2023-07-04 15:36:25 +00:00
|
|
|
SetAnyAnyVal(m, mm, k[i])
|
2023-06-29 15:29:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
key := k[0 : len(k)-1]
|
|
|
|
mm, _ := GetAnyAnyMapVal[map[any]any](m, key...)
|
|
|
|
mm[k[len(k)-1]] = v
|
|
|
|
}
|
2023-07-04 15:36:25 +00:00
|
|
|
|
|
|
|
func AscEahByKey[K constraints.Ordered, V any](m map[K]V, fn func(K, V)) {
|
|
|
|
orderedEahByKey(m, slice.ASC, fn)
|
|
|
|
}
|
|
|
|
func DescEahByKey[K constraints.Ordered, V any](m map[K]V, fn func(K, V)) {
|
|
|
|
orderedEahByKey(m, slice.ASC, fn)
|
|
|
|
}
|
|
|
|
|
|
|
|
func orderedEahByKey[K constraints.Ordered, V any](m map[K]V, ordered int, fn func(K, V)) {
|
|
|
|
keys := Keys(m)
|
|
|
|
slice.Sorts(keys, ordered)
|
|
|
|
for _, key := range keys {
|
|
|
|
fn(key, m[key])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Flip[K, V comparable](m map[K]V) map[V]K {
|
|
|
|
mm := make(map[V]K, len(m))
|
|
|
|
for k, v := range m {
|
|
|
|
mm[v] = k
|
|
|
|
}
|
|
|
|
return mm
|
|
|
|
}
|