将数组键和值数组转换为对象

时间:2015-12-10 21:47:54

标签: arrays json jq

由于涉及从Apple plist到xml2json的旅行的复杂原因,我有许多带有此格式数据的JSON文件:

{ 
  "key": [ "key1", "key2", "key3" ],
  "string": [ "value1", "value2", "value3" ]
}

我想将其转换为普通的JSON对象:

{ 
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"     
}

经过一番抨击后,我想出了这个jq程序来做这个伎俩:

jq '. as $d|[range(.key|length)|{"key":$d.key[.],"value":$d.string[.]}]|from_entries'

这有效,但似乎有点复杂。我想知道是否有更清洁的解决方案?

这确实类似于this question,但区别在于这是一个具有命名键和值元素的对象,而只是一个直接包含两个数组的数组。

2 个答案:

答案 0 :(得分:4)

您提供的脚本已经非常好了!脚本的这种变化将索引保存到变量而不是输入对象中,这对我来说感觉更自然。然后它创建一个由一个关键对象组成的数组并将它们加在一起。

SIGKILL

当我第一次看到这个问题时,我认为jq '[range(.key | length) as $i | {(.key[$i]): .string[$i]}] | add' 内置会改善这种情况。然后我记得:已经内置了zip!它叫做zip。使用它,您可以创建如下脚本:

transpose

对我来说似乎也更容易,虽然它也很长;但是,我认为重点是可读性而不是字符数。当然,您也可以混淆两种解决方案:

jq '[.key, .string] | transpose | map({key: .[0], value: .[1]}) | from_entries'

答案 1 :(得分:0)

这是一个解决方案,它使用 reduce 和一个包含迭代索引和结果对象的状态对象。它迭代.key设置.string

结果中的相应值
  .string as $v
| reduce .key[] as $k (
   {idx:0, result:{}}; .result[$k] = $v[.idx] | .idx += 1
  )
| .result