【问题标题】:Turn array of keys and array of values into object将键数组和值数组转换为对象
【发布时间】:2015-12-10 21:47:53
【问题描述】:

由于复杂的原因,涉及从 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,但不同的是这是一个具有命名键和值元素的对象,而不是一个直接包含两个数组的数组。

【问题讨论】:

标签: arrays json jq


【解决方案1】:

你提供的脚本已经很不错了!您的脚本的这种变体将索引保存到变量而不是输入对象中,这对我来说读起来更自然。然后它创建一个包含一个键对象的数组并将它们添加到一起。

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'

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

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

【讨论】:

    【解决方案2】:

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

      .string as $v
    | reduce .key[] as $k (
       {idx:0, result:{}}; .result[$k] = $v[.idx] | .idx += 1
      )
    | .result
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 2021-02-14
      • 1970-01-01
      • 2017-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多