从键和值的数组中创建对象

8

我已经在这个问题上苦思冥想了几个小时,但似乎找不到解决的办法。我有一个键数组和一个值数组,如何生成一个对象呢?输入:

[["key1", "key2"], ["val1", "val2"]]

输出:

{"key1": "val1", "key2": "val2"}
5个回答

9

github上已解决此问题:

.[0] as $keys |
.[1] as $values |
reduce range(0; $keys|length) as $i  ( {}; . + { ($keys[$i]): $values[$i] })

3

当前版本的jq有一个transpose过滤器,可用于配对键和值。您可以使用它轻松构建结果对象。

transpose | reduce .[] as $pair ({}; .[$pair[0]] = $pair[1])

谢谢Jeff,但我不确定它是否完全有效。我尝试了一下,第一部分似乎生成了每个键/值组合,但是from_entries似乎用错误的键/值对覆盖了正确的键/值对。这就是我得到的结果:{ "key1": "val2", "key2": "val2" } - Abdullah Jibaly
1
啊,我知道叉积可能会有问题。当我检查它时,我认为它没问题。太糟糕了,没有内置的“zip”过滤器。如果有的话,那就太容易了。 - Jeff Mercado
不需要使用 from_entries。也就是说:transpose | map({ (.[0]): .[1] }) | add - peak

2

明确一点:

(0) Abdullah Jibaly的解决方案简单、直接、高效和通用,应该适用于所有版本的jq;

(1) transpose/0是在jq 1.5中内置的,并且自2014年10月以来已经在预发布版中提供;

(2) 使用transpose/0(或如上定义的zip/0),问题的解决方案更加简短、快速和通用。

transpose | map( {(.[0]): .[1]} ) | add

例子:

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

输入:

[["k1","k2","k3"], [1,2,3] ]

输出:

{
  "k1": 1,
  "k2": 2,
  "k3": 3
}

1

放弃这个方法,对于长度大于2的数组实际上并不起作用。

[map(.[0]) , map(.[1])] | map({(.[0]):.[1]}) | add

我以为这很容易,因为我有一点Prolog的经验...哦天啊。最后我也撞了墙头。我想我以后不会再使用jq了。


1
感谢您的努力!我实际上已经找到了答案(请参见更新的问题)。 - Abdullah Jibaly
如果我们拥有一些更典型的函数方法,比如zip,那就不会太糟糕了。幸运的是,实现起来也不会太麻烦。 - Jeff Mercado

0

这是一个使用reduce的解决方案,其中状态对象保存迭代索引和结果对象。它遍历.[0]中的键,并从.[1]设置相应的结果值

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

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