9

I've been banging my head against the wall for several hours on this and just can't seem to find a way to do this. I have an array of keys and an array of values, how can I generate an object? Input:

[["key1", "key2"], ["val1", "val2"]]

Output:

{"key1": "val1", "key2": "val2"}
0

5 Answers 5

10

Resolved this on github:

.[0] as $keys |
.[1] as $values |
reduce range(0; $keys|length) as $i  ( {}; . + { ($keys[$i]): $values[$i] })
Sign up to request clarification or add additional context in comments.

Comments

3

The current version of jq has a transpose filter that can be used to pair up the keys and values. You could use it to build out the result object rather easily.

transpose | reduce .[] as $pair ({}; .[$pair[0]] = $pair[1])

3 Comments

Thanks Jeff, I'm not sure that quite works though. I played around with it and the first portion seems to generate every key/val combination, but then the from_entries seems to override the right key/val pair with the wrong one. This is what I'm getting: { "key1": "val2", "key2": "val2" }
Ah dang it, I knew that cross products might be an issue. When I checked it I thought it was fine. It's too bad there isn't a builtin zip filter. Then it would be trivial.
There is no need to use from_entries. That is: transpose | map({ (.[0]): .[1] }) | add
2

Just to be clear:

(0) Abdullah Jibaly's solution is simple, direct, efficient and generic, and should work in all versions of jq;

(1) transpose/0 is a builtin in jq 1.5 and has been available in pre-releases since Oct 2014;

(2) using transpose/0 (or zip/0 as defined above), an even shorter but still simple, fast, and generic solution to the problem is:

transpose | map( {(.[0]): .[1]} ) | add

Example:

$ jq 'transpose | map( {(.[0]): .[1]} ) | add'

Input:

[["k1","k2","k3"], [1,2,3] ]

Output:

{
  "k1": 1,
  "k2": 2,
  "k3": 3
}

Comments

1

Scratch this, it doesn't actually work for any array greater than size 2.

[map(.[0]) , map(.[1])] | map({(.[0]):.[1]}) | add

Welp, I thought this would be easy, having a little prolog experience... oh man. I ended up banging my head against a wall too. Don't think I'll ever use jq ever again.

2 Comments

Thanks for the effort! I actually found the answer (see updated Q).
It's actually not too bad if we had some of the more typical functional methods such as zip built in. Fortunately it's not too bad implementing it.
0

Here is a solution which uses reduce with a state object holding an iteration index and a result object. It iterates over the keys in .[0] setting corresponding values in the result from .[1]

  .[1] as $v
| reduce .[0][] as $k (
   {idx:0, result:{}}; .result[$k] = $v[.idx] | .idx += 1
  )
| .result

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.