为什么jq的列表构造器与对象构造器对生成器的处理行为不同?
jq 笛卡尔积行为差异原因解答
核心差异来自 jq 迭代器的组合规则,由承载迭代器的语法结构决定:
- 数组构造器内的逗号仅做值的顺序拼接,不触发笛卡尔积
[exp1, exp2]结构中,逗号的作用是按顺序输出所有表达式的返回值,不会对多值返回的表达式做交叉组合。你写的.[0][]会依次输出1、2、3三个值,.[1][]依次输出4、5、6三个值,所有输出按顺序塞入数组后,最终结果就是[1,2,3,4,5,6]。 - 二元操作符会自动对两侧多值迭代器做笛卡尔积组合
包括+在内的所有二元操作符,只要左右两侧的表达式都返回多个值,就会对两侧的所有取值做全排列遍历,每一组取值分别执行一次操作。你的案例中,左侧.[0][] | tostring返回3个字符串,右侧.[1][] | tostring返回3个字符串,+会执行3*3=9次拼接,输出9个拼接结果,刚好覆盖所有组合。 - 对象构造器会自动对多个键对应的多值迭代器做笛卡尔积组合
jq 的对象构造器{k1: exp1, k2: exp2}中,如果多个键对应的表达式都是多值返回的迭代器,会自动对所有键的取值做全排列组合,每一组取值生成一个独立对象。你的案例中x的取值有3个,y的取值有3个,最终生成9个对象,对应所有x和y的组合。
如果你需要得到预期的二维数组格式笛卡尔积,可以用变量绑定迭代器取值的写法:
echo [[1,2,3],[4,5,6]] | jq '[ .[0][] as $a | .[1][] as $b | [$a, $b] ]'
执行后输出为 [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]],符合你的预期。
内容的提问来源于stack exchange,提问作者PeopleMoutainPeopleSea
相关产品推荐
相关产品推荐

