如何使用jq交换对象的键和值?

17

使用jq,我想将一个JSON对象反转,使属性成为值,值成为键。

源代码:

{ 
    "123": "Foobar"
    "567": "Poit"
} 

目标:

{ 
    "Foobar": "123"
    "Poit": "567"
} 

我该如何实现这个目标?

3个回答

27

在您的特定情况下:

to_entries | map( {(.value) : .key } ) | add

更加强健:

to_entries | map( {(.value|tostring) : .key } ) | add

或者,如果你更喜欢:

with_entries( .key as $k | .key = (.value|tostring) | .value = $k )

注意:所有这些都有可能造成损失。


9
如果一些键具有相等的值,那么您可能希望获得作为值的键数组:
to_entries
| map( {(.value) : {(.key):null} } )
| reduce .[] as $item ({}; . * $item)
| to_entries
| map({key:.key, value:(.value|keys)})
| from_entries

输入:

{
  "key1": "val0",
  "key2": "val1",
  "key3": "val1"
}

输出:

{
  "val0": ["key1"],
  "val1": ["key2", "key3"]
}

2
我会采用类似于@peak答案的方法,但不使用add方法。
首先使用to_entries方法获取以下输出:
-> to_entries
Output:
[
  {
    "key": "123",
    "value": "Foobar"
  },
  {
    "key": "567",
    "value": "Poit"
  }
]

然后使用map将键和值交换:
-> to_entries | map({key: .value|tostring, value: .key})  ###**tostring** method converts a number to string since keys can't be numbers
Output:
[
  {
    "key": "Foobar",
    "value": "123"
  },
  {
    "key": "Poit",
    "value": "567"
  }
]


最后使用from_entries来移除key/value并返回原始格式:
-> to_entries | map({key: .value|tostring, value: .key}) | from_entries
Output:
{
  "Foobar": "123",
  "Poit": "567"
}


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