Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge arrays #680

Closed
ashleycoker opened this issue Jan 28, 2015 · 6 comments
Closed

Merge arrays #680

ashleycoker opened this issue Jan 28, 2015 · 6 comments
Labels

Comments

@ashleycoker
Copy link

I have two files:

[
  {
    "name": "Aleshia Tomkiewicz",
    "index": 0
  },
  {
    "name": "Evan Zigomalas",
    "index": 1
  }
]

and

[
  {
    "title": "iPad_12345",
    "deviceAuthCode": 12345
  },
  {
    "title": "iPad_12346",
    "deviceAuthCode": 12346
  }
]

How do I merge these to get the result:

[
  {
    "name": "Aleshia Tomkiewicz",
    "index": 0,
    "title": "iPad_12345",
    "deviceAuthCode": 12345
  },
  {
    "name": "Evan Zigomalas",
    "index": 1,
    "title": "iPad_12346",
    "deviceAuthCode": 12346
  }
]
@ghost
Copy link

ghost commented Jan 28, 2015

Okay, so let's say you have your people data over at people.json and your devices data at devices.json; from now on $people and $devices.

A note first, there are two possible interpretations of what you want: one in which you want the element n of $people to be mixed with the element n of $devices, and one in which you want the element of $people whose index property is n to be mixed with the element n of $devices. I'm assuming the former for now.

Under that assumption, what you want is to pair the elements of your two arrays with each other, then add them together. On jq, you can "zip" them with the transpose function by putting them in an array, and then add the elements of the resulting array with add:

jq -n --argfile people people.json --argfile devices devices.json '[$people, $devices] | transpose | map(add)'

If, instead, you want to match them by the index property, then what you need to do is to map each of the $people values to the result of adding itself to the value at $devices at .index; that is:

jq -n --argfile people people.json --argfile devices devices.json '$people | map(. + $devices[.index])'

Hope this helps!

@ashleycoker
Copy link
Author

Thanks for helping....

error: transpose is not defined

...cant see it in docs either....

@ghost
Copy link

ghost commented Jan 28, 2015

Oh, right, sorry, transpose was defined on the master branch relatively recently. I forgot it wasn't available yet. This should work, although if your version is old maybe the --argfile command-line option is not available and that would really suck.

jq -n --argfile people people.json --argfile devices devices.json '$people | to_entries | map(.value + $devices[.key])'

@ashleycoker
Copy link
Author

You are a life saver!
That works perfectly!
I got as far as using to_entries but then got stuck! I will spend the time to learn from this. Thanks a lot for your help ;-)

@ashleycoker
Copy link
Author

By the way this also works without --argfile by using slurp:

jq '.[0] as $people | .[1] as $devices | $people | to_entries | map(.value + $devices[.key])' -s json/people.json json/devices.json 

@pkoppstein
Copy link
Contributor

To zip the two together constructively using jq 1.4:

jq -n --argfile people 680_1.json --argfile devices 680_2.json '
  reduce range(0; $people|length) as $i ([]; . + [ $people[$i] + $devices[$i] ])'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants