How do i add an index in jq

橙三吉。 提交于 2020-12-29 13:09:37

问题


I want to use jq map my input

["a", "b"]

to output

[{name: "a", index: 0}, {name: "b", index: 1}]

I got as far as

0 as $i | def incr: $i = $i + 1; [.[] | {name:., index:incr}]'

which outputs:

[
  {
    "name": "a",
    "index": 1
  },
  {
    "name": "b",
    "index": 1
  }
]

But I'm missing something.

Any ideas?


回答1:


It's easier than you think.

to_entries | map({name:.value, index:.key})

to_entries takes an object and returns an array of key/value pairs. In the case of arrays, it effectively makes index/value pairs. You could map those pairs to the items you wanted.




回答2:


A more "hands-on" approach is to use reduce: ["a", "b"] | . as $in | reduce range(0;length) as $i ([]; . + [{"name": $in[$i], "index": $i}])




回答3:


Here are a few more ways. Assuming input.json contains your data

["a", "b"]

and you invoke jq as

jq -M -c -f filter.jq input.json

then any of the following filter.jq filters will generate

{"name":"a","index":0}
{"name":"b","index":1}

1) using keys and foreach

   foreach keys[] as $k (.;.;[$k,.[$k]])
 | {name:.[1], index:.[0]}

EDIT: I now realize a filter of the form foreach E as $X (.; .; R) can almost always be rewritten as E as $X | R so the above is really just

   keys[] as $k
 | [$k, .[$k]]
 | {name:.[1], index:.[0]}

which can be simplified to

   keys[] as $k
 | {name:.[$k], index:$k}

2) using keys and transpose

   [keys, .]
 | transpose[]
 | {name:.[1], index:.[0]}

3) using a function

 def enumerate:
    def _enum(i):
      if   length<1
      then empty
      else [i, .[0]], (.[1:] | _enum(i+1))
      end
    ;
    _enum(0)
  ;

   enumerate
 | {name:.[1], index:.[0]}


来源:https://stackoverflow.com/questions/24528256/how-do-i-add-an-index-in-jq

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!