Home > Mobile >  Unique count of json key/values using jq
Unique count of json key/values using jq

Time:09-16

I'm really struggling trying to do this, so I apologize (jq isn't my forte).

I have a file with a json array like this one:

[
  {
    "name": "aaaaa",
    "description": "aaaaa",
    "attributes": [
      {
        "trait": "Color 1",
        "value": "Blue"
      },
      {
        "trait": "Color 2",
        "value": "Yellow"
      },
      {
        "trait": "Hair",
        "value": "Wild"
      }
    ]
  },
  {
    "name": "bbbbb",
    "description": "bbbbbb",
    "attributes": [
      {
        "trait": "Color 1",
        "value": "Blue"
      },
      {
        "trait": "Color 2",
        "value": "Red"
      },
      {
        "trait": "Hair",
        "value": "Wild"
      }
    ]
  }
]

I'd like to output a json object that shows the count of each trait so the end result would include something like

{
   "Color 1": {
        "Blue":2
   },
   "Color 2":{
        "Yellow":1,
        "Red":1
   },
   "Hair":{
        "Wild":2
   }
}
  

This is probably not too difficult but like I said, I suck at jq :)

CodePudding user response:

Having in mind the concepts of group by and bag-of-words as defined by:

def bow(stream): 
  reduce stream as $word ({}; .[($word|tostring)]  = 1);

it's not hard to see that the following produces the result shown immediately below:

map(.attributes[])
| group_by(.trait)
| map( { (.[0].trait):  bow(.[].value) } )
[{"Color 1":{"Blue":2}},{"Color 2":{"Yellow":1,"Red":1}},{"Hair":{"Wild":2}}]

So to get the result you want, simply add | add to the pipeline.

CodePudding user response:

const traits = input.reduce((aggr, obj) => aggr.concat(obj.attributes), []);
const traitSet = traits.reduce((aggr, {trait, value}) => {
 if(!aggr[trait]) {
   aggr[trait] = {};
 }

 if(!aggr[trait][value]){
  aggr[trait][value] = 0;
 }

 aggr[trait][value] = aggr[trait][value]   1
 return aggr;
}, {});


console.log(traitSet);
// or console.log(JSON.stringify(traitSet)) - since you asked for JSON

Just a very quick version and vanilla version. This code can be made chained or less verbose by using libraries like lodash.

  • Related