Home > database >  JQ - unique count of each value in an array
JQ - unique count of each value in an array

Time:07-14

I'm needing to solve this with JQ. I have a large lists of arrays in my json file and am needing to do some sort | uniq -c types of stuff on them. Specifically I have a relatively nasty looking fruit array that needs to break down what is inside. I'm aware of unique and things like that, and imagine there is likely a simple way to do this, but I've been trying run down assigning things as variables and appending and whatnot, but I can't get the most basic part of counting the unique values per that fruit array, and especially not without breaking the rest of the content (hence the variable ideas). Please tell me I'm overthinking this.

I'd like to turn this;

[
  {
    "uid": "123abc",
    "tID": [
      "T19"
    ],
    "fruit": [
      "Kiwi",
      "Apple",
      "",
      "",
      "",
      "Kiwi",
      "",
      "Kiwi",
      "",
      "",
      "Mango",
      "Kiwi"
    ]
  },
  {
    "uid": "456xyz",
    "tID": [
      "T15"
    ],
    "fruit": [
      "",
      "Orange"
    ]
  }
]

Into this;

[
  {
    "uid": "123abc",
    "tID": [
      "T19"
    ],
    "metadata": [
      {
        "name": "fruit",
        "value": "Kiwi - 3"
      },
      {
        "name": "fruit",
        "value": "Mango - 1"
      },
      {
        "name": "fruit",
        "value": "Apple - 1"
      }
    ]
  },
  {
    "uid": "456xyz",
    "tID": [
      "T15"
    ],
    "metadata": [
      {
        "name": "fruit",
        "value": "Orange - 1"
      }
    ]
  }
]

CodePudding user response:

Using group_by and length would be one way:

jq '
  map(with_entries(select(.key == "fruit") |= (
    .value |= (group_by(.) | map(
      {name: "fruit", value: "\(.[0] | select(. != "")) - \(length)"}
    ))
    | .key = "metadata"
  )))
'
[
  {
    "uid": "123abc",
    "tID": [
      "T19"
    ],
    "metadata": [
      {
        "name": "fruit",
        "value": "Apple - 1"
      },
      {
        "name": "fruit",
        "value": "Kiwi - 4"
      },
      {
        "name": "fruit",
        "value": "Mango - 1"
      }
    ]
  },
  {
    "uid": "456xyz",
    "tID": [
      "T15"
    ],
    "metadata": [
      {
        "name": "fruit",
        "value": "Orange - 1"
      }
    ]
  }
]

Demo

  • Related