Skip to content

Commit

Permalink
fix nested array access (#104)
Browse files Browse the repository at this point in the history
Co-authored-by: Earncef Sequeira <earncef.sequeira@beamery.com>
  • Loading branch information
geseq and Earncef Sequeira committed Jul 16, 2021
1 parent a5b1e6c commit 0ea374a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 9 deletions.
32 changes: 23 additions & 9 deletions accessors.go
Expand Up @@ -116,9 +116,15 @@ func getKey(s string) (string, string) {
func access(current interface{}, selector string, value interface{}, isSet bool) interface{} {
thisSel, nextSel := getKey(selector)

index := -1
if strings.Contains(thisSel, "[") {
indexes := []int{}
for strings.Contains(thisSel, "[") {
prevSel := thisSel
index := -1
index, thisSel = getIndex(thisSel)
indexes = append(indexes, index)
if prevSel == thisSel {
break
}
}

if curMap, ok := current.(Map); ok {
Expand All @@ -134,7 +140,7 @@ func access(current interface{}, selector string, value interface{}, isSet bool)
}

_, ok := curMSI[thisSel].(map[string]interface{})
if (curMSI[thisSel] == nil || !ok) && index == -1 && isSet {
if (curMSI[thisSel] == nil || !ok) && len(indexes) == 0 && isSet {
curMSI[thisSel] = map[string]interface{}{}
}

Expand All @@ -144,15 +150,23 @@ func access(current interface{}, selector string, value interface{}, isSet bool)
}

// do we need to access the item of an array?
if index > -1 {
if array, ok := interSlice(current); ok {
if index < len(array) {
current = array[index]
} else {
current = nil
if len(indexes) > 0 {
num := len(indexes)
for num > 0 {
num--
index := indexes[num]
indexes = indexes[:num]
if array, ok := interSlice(current); ok {
if index < len(array) {
current = array[index]
} else {
current = nil
break
}
}
}
}

if nextSel != "" {
current = access(current, nextSel, value, isSet)
}
Expand Down
19 changes: 19 additions & 0 deletions accessors_test.go
Expand Up @@ -218,3 +218,22 @@ func TestAccessorsSet(t *testing.T) {

assert.Equal(t, "Mat", m.Get("name").Data())
}

func TestAccessorsNested(t *testing.T) {
d := objx.MustFromJSON(`{"values":[["test", "test1"], ["test2", {"name":"Mat"}, {"names": ["Captain", "Mat"]}]]}`)

value := d.Get("values[0][0]").String()
assert.Equal(t, "test", value)

value = d.Get("values[0][1]").String()
assert.Equal(t, "test1", value)

value = d.Get("values[1][0]").String()
assert.Equal(t, "test2", value)

value = d.Get("values[1][1].name").String()
assert.Equal(t, "Mat", value)

value = d.Get("values[1][2].names[0]").String()
assert.Equal(t, "Captain", value)
}

0 comments on commit 0ea374a

Please sign in to comment.