Skip to content

Commit

Permalink
Adds funk.Get support for complex map keys
Browse files Browse the repository at this point in the history
  • Loading branch information
marcinc committed Aug 25, 2022
1 parent dfe9213 commit fd33641
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
20 changes: 12 additions & 8 deletions README.rst
Expand Up @@ -445,15 +445,19 @@ Retrieves the value at path of struct(s) or map(s).
}
foo2 := &map[string]interface{}{
"ID": 1,
"FirstName": "Dark",
"LastName": "Vador",
"Age": 30,
"ID": 1,
"FirstName": "Dark",
"LastName": "Vador",
"Age": 30,
"Labels": map[string]interface{} {
"example.com/hello": "world",
},
} // foo2.Bar is nil
funk.Get(bar, "Name") // "Test"
funk.Get([]map[string]interface{}{foo1, foo2}, "Bar.Name") // []string{"Test"}
funk.Get(foo2, "Bar.Name") // nil
funk.Get(foo2, `Labels."example.com/hello"`) // world
``funk.Get`` also handles ``nil`` values:
Expand Down Expand Up @@ -503,7 +507,7 @@ Set value at a path of a struct
.. code-block:: go
var bar Bar = Bar{
Name: "level-0",
Name: "level-0",
Bar: &Bar{
Name: "level-1",
Bars: []*Bar{
Expand Down Expand Up @@ -825,14 +829,14 @@ Generates a sharded string with a fixed length and depth.
funk.Subset
.............

Returns true if a collection is a subset of another
Returns true if a collection is a subset of another

.. code-block:: go
funk.Subset([]int{1, 2, 4}, []int{1, 2, 3, 4, 5}) // true
funk.Subset([]string{"foo", "bar"},[]string{"foo", "bar", "hello", "bar", "hi"}) //true
Performance
-----------

Expand Down
12 changes: 11 additions & 1 deletion retrieve.go
Expand Up @@ -80,7 +80,17 @@ func get(value reflect.Value, path string) reflect.Value {
return resultSlice
}

parts := strings.Split(path, ".")
quoted := false
parts := strings.FieldsFunc(path, func(r rune) bool {
if r == '"' {
quoted = !quoted
}
return !quoted && r == '.'
})

for i, part := range parts {
parts[i] = strings.Trim(part, "\"")
}

for _, part := range parts {
value = redirectValue(value)
Expand Down
5 changes: 4 additions & 1 deletion retrieve_test.go
Expand Up @@ -50,12 +50,15 @@ func TestGetMap(t *testing.T) {
is := assert.New(t)
m := map[string]interface{}{
"bar": map[string]interface{}{
"name": "foobar",
"name": "foobar",
"example.com/hello": "world",
},
}

is.Equal("foobar", Get(m, "bar.name"))
is.Equal("world", Get(m, `bar."example.com/hello"`))
is.Equal(nil, Get(m, "foo.name"))
is.Equal(nil, Get(m, `foo."example.com/hello"`))
is.Equal([]interface{}{"dark", "dark"}, Get([]map[string]interface{}{m1, m2}, "firstname"))
is.Equal([]interface{}{"test"}, Get([]map[string]interface{}{m1, m2}, "bar.name"))
}
Expand Down

0 comments on commit fd33641

Please sign in to comment.