Search code examples
jsonjq

jq how to merge multiple arrays?


I have the following data, the output of multiple jq pipes:

 [
   {
     "Russia": 1073849
   }
 ]
 [
   {
     "Spain": 593730
   }
 ]
 [
   {
     "France": 387252
   }
 ]
 [
   {
     "UK": 371125
   }
 ]

My desired output is:

 [
   {
     "Russia": 1073849
   },
   {
     "Spain": 593730
   },
   {
     "France": 387252
   },
   {
     "UK": 371125
   }
 ]

Based on similar questions I tried '.[]|transpose|map(add)' and it gives an error: Cannot index object with number. Also I cannot group_by(key) because there is no common key in the objects.


Solution

  • If I understand correctly, you want to produce an array as output. You can move your array wrapper from around the final object to the entire jq call to do this:

    url=https://raw.githubusercontent.com/qualified/challenge-data/605fb67/corona.json
    curl -s $url | 
    jq '[ .data[] 
          | select(.continent | test("Europe"))
          | {(.country): .cases} 
        ]'
    

    Output after | [0:4]:

    [
      {
        "Russia": 1073849
      },
      {
        "Spain": 603167
      },
      {
        "France": 395104
      },
      {
        "UK": 374228
      }
    ]
    

    If you want an object, you could use:

    curl -s $url | 
    jq '[ .data[]
          | select(.continent | test("Europe"))
        ] 
        | map({(.country): .cases}) 
        | add'
    

    or:

    curl -s $url | 
    jq '[ .data[]
          | select(.continent | test("Europe"))
        ]
        | reduce .[] as $e ({}; .[$e.country] = $e.cases)'
    

    Output:

    {
      "Russia": 1073849,
      "Spain": 603167,
      "France": 395104,
      "UK": 374228,
      "Italy": 289990,
      "Germany": 264375,
      "Ukraine": 159702,
      "Romania": 105298,
      "Belgium": 94306,
      "Sweden": 87345,
      "Netherlands": 84778,
      "Poland": 75134,
      "Belarus": 74552,
      "Portugal": 65021,
      "Switzerland": 47751,
      "Moldova": 43734,
      "Czechia": 38187,
      "Austria": 34305,
      "Serbia": 32511,
      "Ireland": 31549,
      "Bosnia": 23929,
      "Denmark": 20571,
      "Bulgaria": 18061,
      "Macedonia": 15925,
      "Hungary": 13879,
      "Croatia": 13749,
      "Greece": 13730,
      "Norway": 12330,
      "Albania": 11672,
      "Finland": 8725,
      "Luxembourg": 7244,
      "Montenegro": 6900,
      "Slovakia": 5768,
      "Slovenia": 3831,
      "Lithuania": 3397,
      "Estonia": 2722,
      "Malta": 2454,
      "Iceland": 2174,
      "Latvia": 1482,
      "Andorra": 1438,
      "San Marino": 723,
      "Channel Islands": 639,
      "Faroe Islands": 428,
      "Isle of Man": 339,
      "Gibraltar": 334,
      "Monaco": 177,
      "Liechtenstein": 111,
      "Holy See (Vatican City State)": 12
    }
    

    Although it doesn't matter on this dataset, I'd prefer using == "Europe" rather than test("Europe") which is a bit less precise.