使用 jq,将对象数组转换为具有命名键的对象

47

给定一个格式为json的文件:

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

我该如何使用jq将其转换为类似这样的内容:

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

jq '{(.[].name) : "the name"}' 'myfile.json'让我得到了一个具有[].name键的对象,但我该如何将该对象分配给它?


你能贴一些代码吗?这个网站不旨在为你的练习提供完整的解决方案。 - Massimo Petrus
2个回答

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

(tostring的作用是为了安全/健壮性。)

INDEX/1

如果你的jq具有 INDEX/1(在版本1.5发布后引入),你可以简单地编写:

INDEX(.name)

2
不过最后需要加上一个 add,因为他想要结果作为一个对象。 - Jeff Mercado
感谢,@JeffMercado。 - peak
谢谢,这个很好用。我还在努力适应 jq 的强大功能,但是我经常发现的例子要么太简单,要么太复杂。 - Mike N
1
抱歉,也许我很蠢,但你能给一个完整的例子来说明如何使用 INDEX 吗?我得到了这个错误:jq: error: INDEX/1 is not defined at <top-level> -- 但是我确实有 jq 1.5。 - mpen
1
“after” 的意思是 “之后”。要查看其定义,请在 Google 上搜索:def INDEX builtin.jq。 - peak
这将在值对象中包含.name,这可能是多余的。您可以使用{ (.name|tostring): del(.name) }来删除它。 - BallpointBen

38

只需遍历数组中的项目即可建立一个新对象。 将项目添加到对象中,name作为键。

reduce .[] as $i ({}; .[$i.name] = $i)

reduce 比 INDEX 更高效。 - Manatax
更加灵活,因为您可以即时进行转换,并且对于JS开发人员来说更加熟悉。 - randomsock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接