From db0033701cccc8e2e43b77d03e4f509a48b6b2f2 Mon Sep 17 00:00:00 2001 From: tidwall Date: Tue, 30 Nov 2021 17:20:07 -0700 Subject: [PATCH] Set array index as key for ForEach See #248 --- gjson.go | 10 +++++++--- gjson_test.go | 26 +++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/gjson.go b/gjson.go index 8783aac..9920c4d 100644 --- a/gjson.go +++ b/gjson.go @@ -229,17 +229,19 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { return } json := t.Raw - var keys bool + var obj bool var i int var key, value Result for ; i < len(json); i++ { if json[i] == '{' { i++ key.Type = String - keys = true + obj = true break } else if json[i] == '[' { i++ + key.Type = Number + key.Num = -1 break } if json[i] > ' ' { @@ -251,7 +253,7 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { var ok bool var idx int for ; i < len(json); i++ { - if keys { + if obj { if json[i] != '"' { continue } @@ -267,6 +269,8 @@ func (t Result) ForEach(iterator func(key, value Result) bool) { } key.Raw = str key.Index = s + t.Index + } else { + key.Num += 1 } for ; i < len(json); i++ { if json[i] <= ' ' || json[i] == ',' || json[i] == ':' { diff --git a/gjson_test.go b/gjson_test.go index bb084ea..d79bcdf 100644 --- a/gjson_test.go +++ b/gjson_test.go @@ -435,9 +435,9 @@ func TestBasic1(t *testing.T) { mtok := get(basicJSON, `loggy.programmers`) var count int mtok.ForEach(func(key, value Result) bool { - if key.Exists() { - t.Fatalf("expected %v, got %v", false, key.Exists()) - } + assert(t, key.Exists()) + assert(t, key.String() == fmt.Sprint(count)) + assert(t, key.Int() == int64(count)) count++ if count == 3 { return false @@ -2441,3 +2441,23 @@ func TestStaticJSON(t *testing.T) { `[true,false,null,inf,nan,{"name":"andy","last":"Anderson"},["any","thing"]]`, ) } + +func TestArrayKeys(t *testing.T) { + N := 100 + json := "[" + for i := 0; i < N; i++ { + if i > 0 { + json += "," + } + json += fmt.Sprint(i) + } + json += "]" + var i int + Parse(json).ForEach(func(key, value Result) bool { + assert(t, key.String() == fmt.Sprint(i)) + assert(t, key.Int() == int64(i)) + i++ + return true + }) + assert(t, i == N) +}