tidwall / gjson

Get JSON values quickly - JSON parser for Go
MIT License
14.1k stars 846 forks source link

Query last item of array #244

Closed itmaple closed 2 years ago

itmaple commented 2 years ago

Why not make -1 to get the last item? such as sjson sjson.Set(json, "-1"...)

tidwall commented 2 years ago

I can see that being useful and something I'll consider.

tidwall commented 2 years ago

Would -2 return the second to last element, and so forth?

itmaple commented 2 years ago

Would -2 return the second to last element, and so forth? Good idea! I think get index from modifier or special character maybe usefully. Like This:


func TestIndex() {
gjson.AddModifier("index", IndexModifier)
jsonA := `{"favourites":[{"name":"abc","sortingOrder":999},{"name":"bcd","sortingOrder":283}]}`
jsonB := `{"favourites":[{"name":1,"sortingOrder":999},{"name":2,"sortingOrder":283}]}`
indexA := gjson.Get(jsonA, `favourites.#.name|@index:"abc"`)
indexB := gjson.Get(jsonB, `favourites.#.name|@index:2`)
fmt.Println(indexA.Int(), indexB.Int())

} func IndexModifier(json, arg string) string { value := gjson.Parse(arg).Value() r := gjson.Parse(json) if !r.IsArray() { return fmt.Sprint(-1) }

for i, v := range r.Array() {
    if v.Value() == value {
        return fmt.Sprint(i)
    }
}
return fmt.Sprint(-1)

}

tidwall commented 2 years ago

Thinking about it further. In SJSON, if -1 adds an element and in GJSON -1 requests the last element, then I could see that being confusing to the developer.

A solution may require a little more thought, but right now using the @reverse modifier can effectively give a similar result.

Take this JSON with these paths for example:

["a","b","c","d"]
"@reverse.0"    -> "d"
"@reverse.1"    -> "c"

As far as the @index modifier idea, perhaps that something worth considering in the future.

itmaple commented 2 years ago

Yeah, thank you! I will close the comment!