From 4c25f5818dce00a61b190c99f4f8d517d31e2a45 Mon Sep 17 00:00:00 2001 From: Vitaliy <160263432+vitalivo@users.noreply.github.com> Date: Sat, 12 Sep 2026 16:05:32 +0300 Subject: [PATCH] Preserve slice elements when setting an indexed value --- accessors.go | 11 +++++++++-- accessors_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/accessors.go b/accessors.go index 72f1d1c..a8038d7 100644 --- a/accessors.go +++ b/accessors.go @@ -134,7 +134,7 @@ func access(current interface{}, selector string, value interface{}, isSet bool) switch current.(type) { case map[string]interface{}: curMSI := current.(map[string]interface{}) - if nextSel == "" && isSet { + if nextSel == "" && isSet && len(indexes) == 0 { curMSI[thisSel] = value return nil } @@ -161,12 +161,19 @@ func access(current interface{}, selector string, value interface{}, isSet bool) index := indexes[num] indexes = indexes[:num] if array, ok := interSlice(current); ok { - if index < len(array) { + if index >= 0 && index < len(array) { + if isSet && nextSel == "" && num == 0 { + array[index] = value + return nil + } current = array[index] } else { current = nil break } + } else { + current = nil + break } } } diff --git a/accessors_test.go b/accessors_test.go index 7b6f1a7..0c1d049 100644 --- a/accessors_test.go +++ b/accessors_test.go @@ -256,3 +256,28 @@ func TestAccessorsNested(t *testing.T) { value = d.Get("values[1][2].names[0]").String() assert.Equal(t, "Captain", value) } + +func TestGetIndexOnNonSlice(t *testing.T) { + for _, value := range []interface{}{42, "text", objx.Map{"name": "value"}, nil} { + m := objx.Map{"value": value} + assert.Nil(t, m.Get("value[0]").Data()) + assert.Nil(t, m.Get("value[0].name").Data()) + } + m := objx.Map{"value": []interface{}{42}} + assert.Nil(t, m.Get("value[0][0]").Data()) + assert.Equal(t, 42, m.Get("value[0]").Data()) +} + +func TestSetIndexPreservesSlice(t *testing.T) { + m := objx.Map{"names": []interface{}{"Tyler", "Sam"}} + m.Set("names[0]", "Mat") + assert.Equal(t, []interface{}{"Mat", "Sam"}, m["names"]) + m.Set("names[2]", "outside") + assert.Equal(t, []interface{}{"Mat", "Sam"}, m["names"]) + m.Set("names[1]", nil) + assert.Equal(t, []interface{}{"Mat", nil}, m["names"]) + + m = objx.Map{"nested": []interface{}{[]interface{}{"first", "second"}}} + m.Set("nested[0][1]", "changed") + assert.Equal(t, []interface{}{[]interface{}{"first", "changed"}}, m["nested"]) +}