tidwall / gjson

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

Getting count of array with a filter does not work as expected #261

Closed thestephenstanton closed 2 years ago

thestephenstanton commented 2 years ago

Using this JSON:

{
  "name": {"first": "Tom", "last": "Anderson"},
  "age":37,
  "children": ["Sara","Alex","Jack"],
  "fav.movie": "Deer Hunter",
  "friends": [
    {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
    {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
    {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
  ]
}

Normal Behavior

If I run gjson.Get(testJSON, "friends") I'll get an array back of the friends. Ok all good. If I run gjson.Get(testJSON, "friends.#") I will get 4 back. Meaning that if I use .# on the end of a path that is an array, I will get the count back.

Problem Behavior

If I run gjson.Get(testJSON, "friends.#(last==\"Murphy\")#") I get an array back of size two and only with friends with the last name Murphy. All good, still works as expected.

HOWEVER, using the same .# at the end of a path that leads to an array, I would expect to get back the count of that array, but I do not. So if I run gjson.Get(testJSON, "friends.#(last==\"Murphy\")#.#") I actually get back an empty array [].

I would expect to get the count of that array which should be 2.

tidwall commented 2 years ago

In this case you will need to use the pipe | character instead of the ., like:

gjson.Get(testJSON, "friends.#(last==\"Murphy\")#|#")

Using a dot after a # is like doing a Get operation on each friend in the array, but using a pipe is like will doing one Get operation on the resulting array.

Here's a little more info:

https://github.com/tidwall/gjson/blob/master/SYNTAX.md#dot-vs-pipe

thestephenstanton commented 2 years ago

Ahhhhh ok I didn't even notice that other set of documentation. This is great. Thank you!

tidwall commented 2 years ago

You're welcome :)