diff --git a/helper/maps/function.go b/helper/maps/function.go index a00fa82..3d1c659 100644 --- a/helper/maps/function.go +++ b/helper/maps/function.go @@ -133,3 +133,29 @@ func RecursiveSetStrVal[T any](m map[string]any, k string, v T) { mm, _ := GetStrAnyVal[map[string]any](m, key) mm[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 +} diff --git a/helper/maps/function_test.go b/helper/maps/function_test.go index ea085b0..331a4d3 100644 --- a/helper/maps/function_test.go +++ b/helper/maps/function_test.go @@ -216,3 +216,65 @@ 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, + }, + }, + } + 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() + } + }) + } +}