使用jq将字符串数组转换为对象数组的实现困惑
用JQ遍历任意长度数组生成对应输出的解决方案
没问题,我来帮你搞定这个JQ遍历数组的问题!首先咱们先拿一个典型场景举例,方便你理解:
假设你的Input JSON是这样的(多个长度一致的字符串/值数组):
{ "names": ["Alice", "Bob", "Charlie", "Diana"], "ages": [25, 30, 35, 40], "roles": ["Engineer", "Designer", "Manager", "Analyst"] }
你的Desired Output是把每个数组对应位置的元素组合成对象,比如:
[ {"name": "Alice", "age": 25, "role": "Engineer"}, {"name": "Bob", "age": 30, "role": "Designer"}, {"name": "Charlie", "age": 35, "role": "Manager"}, {"name": "Diana", "age": 40, "role": "Analyst"} ]
下面给你两种通用的实现方式,不管数组有多少个、长度是多少(只要数组长度一致)都能用:
方法1:用transpose转置数组(简洁高效)
transpose是JQ里专门用来处理二维数组转置的函数,能把多个数组的对应元素打包成子数组,非常适合这种场景:
# 先把所有需要组合的数组打包成二维数组,再转置,最后映射成目标对象 [.names, .ages, .roles] | transpose | map({name: .[0], age: .[1], role: .[2]})
如果你的数组键和输出字段名完全对应,还能写得更通用(不用硬编码字段名):
# 获取所有数组的键名 keys_unsorted as $fieldNames # 把每个数组的值提取出来组成二维数组,转置后,每个子数组是对应位置的所有值 | [$fieldNames[] as $k | .[$k]] | transpose # 把每个子数组和字段名配对,转成键值对后生成对象 | map( [$fieldNames, .] | transpose | from_entries )
这个版本不管你有多少个数组,只要顶层键对应的是长度一致的数组,就能自动生成对应结构的输出,完全不用改代码。
方法2:遍历索引(直观易理解)
如果你更习惯用索引遍历的思路,可以先获取数组的长度,然后遍历每个索引来取对应元素:
# 先获取数组的长度(这里假设所有数组长度一致,用第一个数组的长度即可) (.names | length) as $arrayLength # 遍历从0到$arrayLength-1的所有索引 | range(0; $arrayLength) # 每个索引对应取各个数组的元素,生成目标对象 | {name: .names[.], age: .ages[.], role: .roles[.]}
额外提示:处理数组长度不一致的情况
如果你的数组长度可能不一样,可以取最短数组的长度来避免越界:
# 计算所有数组的最小长度 ([.names, .ages, .roles] | map(length) | min) as $minLength | range(0; $minLength) | {name: .names[.], age: .ages[.], role: .roles[.]}
这样就能保证遍历过程不会因为某个数组更短而报错啦!
内容的提问来源于stack exchange,提问作者Mat Ford
相关产品推荐
相关产品推荐

