Compare commits
2 Commits
879238cda1
...
a4274b74dd
Author | SHA1 | Date | |
---|---|---|---|
a4274b74dd | |||
03b448e70c |
@ -2,14 +2,18 @@ package maps
|
|||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
||||||
func GetStrAnyVal[T any](m map[string]any, key string) (r T, o bool) {
|
func GetStrAnyVal[T any](m map[string]any, key string, delimiter ...string) (r T, o bool) {
|
||||||
k := strings.Split(key, ".")
|
separator := "."
|
||||||
|
if len(delimiter) > 0 && delimiter[0] != "" {
|
||||||
|
separator = delimiter[0]
|
||||||
|
}
|
||||||
|
k := strings.Split(key, separator)
|
||||||
if len(k) > 1 {
|
if len(k) > 1 {
|
||||||
val, ok := m[k[0]]
|
val, ok := m[k[0]]
|
||||||
if ok {
|
if ok {
|
||||||
vx, ok := val.(map[string]any)
|
vx, ok := val.(map[string]any)
|
||||||
if ok {
|
if ok {
|
||||||
r, o = GetStrAnyVal[T](vx, strings.Join(k[1:], "."))
|
r, o = GetStrAnyVal[T](vx, strings.Join(k[1:], separator))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -107,29 +111,65 @@ func GetAnyAnyValWithDefaults[T any](m map[any]any, defaults T, key ...any) (r T
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func RecursiveSetStrVal[T any](m map[string]any, k string, v T) {
|
func RecursiveSetStrVal[T any](m map[string]any, k string, v T, delimiter ...string) {
|
||||||
kk := strings.Split(k, ".")
|
del := "."
|
||||||
|
if len(delimiter) > 0 && delimiter[0] != "" {
|
||||||
|
del = delimiter[0]
|
||||||
|
}
|
||||||
|
kk := strings.Split(k, del)
|
||||||
if len(kk) < 1 {
|
if len(kk) < 1 {
|
||||||
return
|
return
|
||||||
} else if len(kk) < 2 {
|
} else if len(kk) < 2 {
|
||||||
m[k] = v
|
m[k] = v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i, _ := range kk[0 : len(kk)-1] {
|
mm, ok := GetStrAnyVal[map[string]any](m, strings.Join(kk[0:len(kk)-1], del))
|
||||||
key := strings.Join(kk[0:i+1], ".")
|
if ok {
|
||||||
mm, ok := GetStrAnyVal[map[string]any](m, key)
|
|
||||||
if !ok {
|
|
||||||
mm = map[string]any{}
|
|
||||||
preKey := strings.Join(kk[0:i], ".")
|
|
||||||
if preKey == "" {
|
|
||||||
RecursiveSetStrVal(m, key, mm)
|
|
||||||
} else {
|
|
||||||
m, _ := GetStrAnyVal[map[string]any](m, preKey)
|
|
||||||
RecursiveSetStrVal(m, kk[i], mm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key := strings.Join(kk[0:len(kk)-1], ".")
|
|
||||||
mm, _ := GetStrAnyVal[map[string]any](m, key)
|
|
||||||
mm[kk[len(kk)-1]] = v
|
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]
|
||||||
|
if !ok {
|
||||||
|
mmm := map[string]any{}
|
||||||
|
mx[key] = mmm
|
||||||
|
mx = mmm
|
||||||
|
|
||||||
|
} else {
|
||||||
|
mx = mm.(map[string]any)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mx[kk[len(kk)-1]] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func RecursiveSetAnyVal[T any](m map[any]any, v T, k ...any) {
|
||||||
|
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 {
|
||||||
|
RecursiveSetAnyVal(m, mm, key...)
|
||||||
|
} else {
|
||||||
|
m, _ := GetAnyAnyMapVal[map[any]any](m, preKey...)
|
||||||
|
RecursiveSetAnyVal(m, mm, k[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key := k[0 : len(k)-1]
|
||||||
|
mm, _ := GetAnyAnyMapVal[map[any]any](m, key...)
|
||||||
|
mm[k[len(k)-1]] = v
|
||||||
}
|
}
|
||||||
|
@ -216,3 +216,81 @@ func TestGetAnyAnyValWithDefaults(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRecursiveSetAnyVal(t *testing.T) {
|
||||||
|
type args[T any] struct {
|
||||||
|
m map[any]any
|
||||||
|
v T
|
||||||
|
k []any
|
||||||
|
}
|
||||||
|
type testCase[T any] struct {
|
||||||
|
name string
|
||||||
|
args args[T]
|
||||||
|
}
|
||||||
|
tests := []testCase[float64]{
|
||||||
|
{
|
||||||
|
name: "t1",
|
||||||
|
args: args[float64]{
|
||||||
|
m: map[any]any{},
|
||||||
|
v: 3.4,
|
||||||
|
k: []any{"m", 3, "key"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
target := map[any]any{"m": map[any]any{3: map[any]any{"key": 3.4}}}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
RecursiveSetAnyVal(tt.args.m, tt.args.v, tt.args.k...)
|
||||||
|
if !reflect.DeepEqual(tt.args.m, target) {
|
||||||
|
t.Fatalf("not equal target")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRecursiveSetStrVal(t *testing.T) {
|
||||||
|
type args[T any] struct {
|
||||||
|
m map[string]any
|
||||||
|
k string
|
||||||
|
v T
|
||||||
|
}
|
||||||
|
type testCase[T any] struct {
|
||||||
|
name string
|
||||||
|
args args[T]
|
||||||
|
}
|
||||||
|
tests := []testCase[int]{
|
||||||
|
{
|
||||||
|
name: "t1",
|
||||||
|
args: args[int]{
|
||||||
|
m: map[string]any{},
|
||||||
|
k: "aa.bb.cc",
|
||||||
|
v: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "t2",
|
||||||
|
args: args[int]{
|
||||||
|
m: map[string]any{"aa": map[string]any{}},
|
||||||
|
k: "aa.bb.cc",
|
||||||
|
v: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "t3",
|
||||||
|
args: args[int]{
|
||||||
|
m: map[string]any{"aa": map[string]any{"bb": map[string]any{}}},
|
||||||
|
k: "aa.bb.cc",
|
||||||
|
v: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
target := map[string]any{"aa": map[string]any{"bb": map[string]any{"cc": 1}}}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
RecursiveSetStrVal(tt.args.m, tt.args.k, tt.args.v)
|
||||||
|
if !reflect.DeepEqual(target, tt.args.m) {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user