Home > Mobile >  How to use jq to count all instances of a field that is nested numerically in an array?
How to use jq to count all instances of a field that is nested numerically in an array?

Time:10-01

I have a json structure that looks like:

{  
   "main":[  
      {  
            "0":[ {"0":"..."},{"1":"..."},{"2":"..."},{"3":"..."} ]
      },
      {  
            "1":[ {"0":"..."},{"1":"..."},{"2":"..."} ]
      },
      {  
            "2":[ {"0":"..."},{"1":"..."},{"2":"..."},{"3":"..."},{"4":"..."} ]
      }
    ]
}

What I would like is to be able to count the total number of elements within each direct child of "main". For example, in the above, "main" has an array containing 3 direct childs, "0", "1", "2". For "0", we have 4 such elements, "1" we have 3 such elements, and "2" we have 5 such elements.

Is there a way to use jq to return 12 as the final answer for the above?

CodePudding user response:

Double map length add:

.main|map(map(length)|add)|add

Or

.main|map(map(length))|add|add

Or stream all values first, wrap in array and get array length (this is probably the sexiest shortest):

[.main[][][]]|length

CodePudding user response:

You could count all scalars in the document:

jq '[..|scalars] | length'

Demo

If you just want to consider the tree under .main, prepend it:

jq '.main | [..|scalars] | length'

Demo

If there's many elements and you don't want to buid up an intermediate array, only needed to take its length from, count on the fly using reduce:

jq 'reduce (..|scalars) as $_ (0; . 1)'

Demo

  • Related