tidwall / gjson

Get JSON values quickly - JSON parser for Go
MIT License
13.95k stars 841 forks source link

Iteration over arrays in combination with @this and nested # not working as expected #288

Open boindil opened 2 years ago

boindil commented 2 years ago

While playing around with the library, I tried looping over arrays combined with @this.

The libary does seem to detect whether or not the given path is valid (#.#.#.@this does not work at all as expected) but does not return the expected results. As in the example below, I expected the same results for both loops. Am I missing something here?

Using 0.#.@this works just fine.

https://go.dev/play/p/VKc4RFPEvAL

package main

import (
    "fmt"

    "github.com/tidwall/gjson"
)

const json1 = `
    [{ "a": "b1", "b": "c1", "c": "d1"},
    { "a": "b2", "b": "c2", "c": "d2"},
    { "a": "b3", "b": "c3", "c": "d3"},
    { "a": "b4", "b": "c4", "c": "d4"},
    {"foo":"bar"}]
`
const json2 = `[ 
    [{ "a": "b1", "b": "c1", "c": "d1"},
    { "a": "b2", "b": "c2", "c": "d2"},
    { "a": "b3", "b": "c3", "c": "d3"},
    { "a": "b4", "b": "c4", "c": "d4"}], 
    [{"foo":"bar"}]
]`

func main() {
    result := gjson.Get(json1, "#.@this")
    result.ForEach(func(key, value gjson.Result) bool {
        fmt.Println(value)
        return true // keep iterating
    })
    fmt.Println("---")
    result = gjson.Get(json2, "#.#.@this")
    result.ForEach(func(key, value gjson.Result) bool {
        fmt.Println(value)
        return true // keep iterating
    })
}

Output:

{ "a": "b1", "b": "c1", "c": "d1"}
{ "a": "b2", "b": "c2", "c": "d2"}
{ "a": "b3", "b": "c3", "c": "d3"}
{ "a": "b4", "b": "c4", "c": "d4"}
{"foo":"bar"}
---
[{ "a": "b1", "b": "c1", "c": "d1"},{ "a": "b2", "b": "c2", "c": "d2"},{ "a": "b3", "b": "c3", "c": "d3"},{ "a": "b4", "b": "c4", "c": "d4"}]
[{"foo":"bar"}]