skip to Main Content

I am seeking the simultaneous iteration of two lists.

Input object list:

First Input Object List

{
  "k11": "v111",
  "k12": "v112"
}
{
  "k11": "v121",
  "k12": "v122"
}
{
  "k11": "v131",
  "k12": "v132"
}

Second Input Object List

{
  "k21": "v211",
  "k22": "v212"
}
{
  "k21": "v221",
  "k22": "v222"
}
{
  "k21": "v231",
  "k22": "v232"
}

Wanted Output Object List

{
  "k11": "v111",
  "k12": "v112"
  "k21": "v211",
  "k22": "v212"
}
{
  "k11": "v121",
  "k12": "v122"
  "k21": "v221",
  "k22": "v222"
}
{
  "k11": "v131",
  "k12": "v132"
  "k21": "v231",
  "k22": "v232"
}

There are no matching keys between the two object lists (which can easily be turned into arrays).
Thank you for reading this question.

3

Answers


  1. One way would be using --slurpfile to read in the files as arrays, then use transpose and add to "zip" them:

    jq --slurpfile s1 file1.json --slurpfile s2 file2.json -n 
      '[$s1, $s2] | transpose[] | add'
    
    {
      "k11": "v111",
      "k12": "v112",
      "k21": "v211",
      "k22": "v212"
    }
    {
      "k11": "v121",
      "k12": "v122",
      "k21": "v221",
      "k22": "v222"
    }
    {
      "k11": "v131",
      "k12": "v132",
      "k21": "v231",
      "k22": "v232"
    }
    

    the two object lists (which can easily be turned into arrays)

    If the two files were already arrays, you can move from using --slurpfile to a single --slurp (or -s), then reading in the files as regular input files instead, and using the same "zipping" technique:

    jq -s 'transpose[] | add' arrayfile1.json arrayfile2.json
    
    Login or Signup to reply.
  2. As illustrated by the accepted answer, one approach to the problem is to convert both streams to arrays,
    but this imposes an unnecessary memory requirement, as illustrated by the following solution,
    which requires that only one of the two streams be "slurped", and which
    incidentally also does not incur the various costs of transpose.

    < s2 jq -n --slurpfile s1 s1 '
      def zips(s): 
        . as $in
        | foreach s as $x (-1; .+1; $in[.] + $x);
      $s1 | zips(inputs)'
    
    Login or Signup to reply.
  3. I know this is cheating, I just wanted to see if it would work: a shell pipeline

    paste -d+ <(jq -c . file1.json) <(jq -c . file2.json) 
    | paste -sd, 
    | xargs -0 jq -n
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search