From 6300d17f32fb599bebedc9fa033310bad38ce949 Mon Sep 17 00:00:00 2001 From: marcinc Date: Thu, 25 Aug 2022 14:25:57 +0100 Subject: [PATCH 1/2] Adds funk.Get support for complex map keys --- README.rst | 12 ++++++++---- retrieve.go | 12 +++++++++++- retrieve_test.go | 5 ++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 818fc7d..4f6d59c 100644 --- a/README.rst +++ b/README.rst @@ -449,11 +449,15 @@ Retrieves the value at path of struct(s) or map(s). "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: @@ -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{ @@ -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 ----------- diff --git a/retrieve.go b/retrieve.go index 7b3019f..e894961 100644 --- a/retrieve.go +++ b/retrieve.go @@ -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) diff --git a/retrieve_test.go b/retrieve_test.go index 1aee6c6..e30a50a 100644 --- a/retrieve_test.go +++ b/retrieve_test.go @@ -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")) } From ad87c80b503e17cf002ec102eab5fab89f98e345 Mon Sep 17 00:00:00 2001 From: marcinc Date: Tue, 1 Nov 2022 19:19:53 +0000 Subject: [PATCH 2/2] fixup! Adds funk.Get support for complex map keys