45

Given a json file in the format as :

[
 {
  name : "A",
  value : "1"
 },
 {
  name : "B",
  value : "5"
 },
 {
  name : "E",
  value : "8"
 }
]

How would I convert it to something like this using jq:

{
 "A" : {
   name : "A",
   value : "1"
 },
 "B" : {
  name : "B",
  value : "5"
 },
 "E" : {
  name : "E",
  value : "8"
 }
}

jq '{(.[].name) : "the name"}' 'myfile.json' gets me an object with [].name keys but how do I assign the object to it?

peak
  • 105,803
  • 17
  • 152
  • 177
Mike N
  • 453
  • 1
  • 4
  • 4

2 Answers2

73
map( { (.name|tostring): . } ) | add

(The tostring is for safety/robustness.)

INDEX/1

If your jq has INDEX/1 (introduced after the release of version 1.5), you can simply write:

INDEX(.name)
peak
  • 105,803
  • 17
  • 152
  • 177
  • 2
    It would need an `add` at the end though, since he want the result as an object. – Jeff Mercado Feb 24 '17 at 00:04
  • Thanks, @JeffMercado. – peak Feb 24 '17 at 00:08
  • Thanks, this works nicely. Still trying to get used to the power of jq but often the examples I find are too simple or too complicated. – Mike N Feb 24 '17 at 14:14
  • 1
    Sorry, maybe I'm dumb, but can you give a full example of how to use `INDEX`? I'm getting: jq: error: INDEX/1 is not defined at -- but I do have jq 1.5 – mpen Jul 06 '18 at 20:42
  • 1
    "after" means "after". For its definition, google for: def INDEX builtin.jq – peak Jul 06 '18 at 22:21
  • This will include `.name` in the value-objects, which might be redundant. You can remove it with `{ (.name|tostring): del(.name) }` – BallpointBen Aug 17 '23 at 16:04
37

Just build up a new object going through the items in the array. Add the items to the object with the name as the key.

reduce .[] as $i ({}; .[$i.name] = $i)
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272