Skip to content

Commit

Permalink
feat(get): retrieves the value of a path of maps + returns nil when p…
Browse files Browse the repository at this point in the history
…ath not found (instead of exception)
  • Loading branch information
samber committed Mar 10, 2021
1 parent d02a012 commit 7042fde
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 11 deletions.
31 changes: 31 additions & 0 deletions funk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,34 @@ var foo2 = &Foo{
LastName: "Vador",
Age: 30,
}

var m1 = map[string]interface{}{
"id": 1,
"firstname": "dark",
"lastname": "vador",
"age": 30,
"bar": map[string]interface{}{
"name": "test",
"bars": []map[string]interface{}{
{
"name": "level1-1",
"bar": map[string]interface{}{
"name": "level2-1",
},
},
{
"name": "level1-2",
"bar": map[string]interface{}{
"name": "level2-2",
},
},
},
},
}

var m2 = map[string]interface{}{
"id": 1,
"firstname": "dark",
"lastname": "vador",
"age": 30,
}
19 changes: 9 additions & 10 deletions retrieve.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func get(value reflect.Value, path string) reflect.Value {
}

// if the result is a slice of a slice, we need to flatten it
if resultSlice.Type().Elem().Kind() == reflect.Slice {
if resultSlice.Kind() != reflect.Invalid && resultSlice.Type().Elem().Kind() == reflect.Slice {
return flattenDeep(resultSlice)
}

Expand All @@ -60,18 +60,17 @@ func get(value reflect.Value, path string) reflect.Value {
value = redirectValue(value)
kind := value.Kind()

if kind == reflect.Invalid {
switch kind {
case reflect.Invalid:
continue
}

if kind == reflect.Struct {
case reflect.Struct:
value = value.FieldByName(part)
continue
}

if kind == reflect.Slice || kind == reflect.Array {
case reflect.Map:
value = value.MapIndex(reflect.ValueOf(part))
case reflect.Slice, reflect.Array:
value = get(value, part)
continue
default:
return reflect.ValueOf(nil)
}
}

Expand Down
24 changes: 23 additions & 1 deletion retrieve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,36 @@ func TestGetNil(t *testing.T) {
is.Equal(Get([]*Foo{foo, foo2}, "Bar.Name"), []string{"Test"})
}

func TestGetMap(t *testing.T) {
is := assert.New(t)
m := map[string]interface{}{
"bar": map[string]interface{}{
"name": "foobar",
},
}

is.Equal("foobar", Get(m, "bar.name"))
is.Equal(nil, Get(m, "foo.name"))
is.Equal([]interface{}{"dark", "dark"}, Get([]map[string]interface{}{m1, m2}, "firstname"))
is.Equal([]interface{}{"test"}, Get([]map[string]interface{}{m1, m2}, "bar.name"))
}

func TestGetThroughInterface(t *testing.T) {
is := assert.New(t)

is.Equal(Get(foo, "BarInterface.Bars.Bar.Name"), []string{"Level2-1", "Level2-2"})
is.Equal(Get(foo, "BarPointer.Bars.Bar.Name"), []string{"Level2-1", "Level2-2"})
}

func TestGetNotFound(t *testing.T) {
is := assert.New(t)

is.Equal(nil, Get(foo, "id"))
is.Equal(nil, Get(foo, "id.id"))
is.Equal(nil, Get(foo, "Bar.id"))
is.Equal(nil, Get(foo, "Bars.id"))
}

func TestGetSimple(t *testing.T) {
is := assert.New(t)

Expand All @@ -68,5 +91,4 @@ func TestGetOrElse(t *testing.T) {
// test GetOrElse coveers this case
is.Equal("foobar", GetOrElse((*string)(nil), "foobar"))
})

}

0 comments on commit 7042fde

Please sign in to comment.