Skip to content

Commit

Permalink
Merge pull request #23 from iawia002/maps
Browse files Browse the repository at this point in the history
maps: add a helper function to set the value of a nested field for the map
  • Loading branch information
iawia002 authored Feb 1, 2024
2 parents 8bfc56b + 6e20dc2 commit 40d14a2
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
30 changes: 30 additions & 0 deletions maps/maps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package maps

import (
"strings"
)

// SetNestedField sets the value of a nested field (eg: a.b.c) for the source map.
//
// eg:
//
// src := make(map[string]interface{})
// SetNestedField(src, "a.b", 1)
//
// src: map[a:map[b:1]]
func SetNestedField(src map[string]interface{}, key string, value interface{}) {
setValueRecursively(src, strings.Split(key, "."), value)
}

func setValueRecursively(src map[string]interface{}, keys []string, value interface{}) {
if len(keys) == 1 {
src[keys[0]] = value
return
}

currentKey := keys[0]
if _, ok := src[currentKey].(map[string]interface{}); !ok {
src[currentKey] = make(map[string]interface{})
}
setValueRecursively(src[currentKey].(map[string]interface{}), keys[1:], value)
}
69 changes: 69 additions & 0 deletions maps/maps_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package maps

import (
"reflect"
"testing"
)

func TestSetNestedField(t *testing.T) {
tests := []struct {
name string
src map[string]interface{}
key string
value interface{}
wanted map[string]interface{}
}{
{
name: "normal test",
src: map[string]interface{}{
"aa": 1,
},
key: "bb.cc",
value: 1,
wanted: map[string]interface{}{
"aa": 1,
"bb": map[string]interface{}{
"cc": 1,
},
},
},
{
name: "normal test 2",
src: map[string]interface{}{
"aa": 1,
"bb": map[string]interface{}{},
},
key: "bb.cc",
value: 1,
wanted: map[string]interface{}{
"aa": 1,
"bb": map[string]interface{}{
"cc": 1,
},
},
},
{
name: "override test",
src: map[string]interface{}{
"aa": 1,
"bb": 1,
},
key: "bb.cc",
value: 1,
wanted: map[string]interface{}{
"aa": 1,
"bb": map[string]interface{}{
"cc": 1,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
SetNestedField(tt.src, tt.key, tt.value)
if !reflect.DeepEqual(tt.src, tt.wanted) {
t.Errorf("SetNestedField() = %v, want %v", tt.src, tt.wanted)
}
})
}
}

0 comments on commit 40d14a2

Please sign in to comment.