【问题标题】:Is there some way I can achieve the distributive property for arrays in `jq`?有什么方法可以实现“jq”中数组的分配属性吗?
【发布时间】:2018-03-20 04:46:26
【问题描述】:

我想将 2 个数组相乘以产生混合减少。我将此与使用 FOIL 方法进行比较,将多项式之间的括号项展开和分配为代数中的组合表达式。

我希望避免编写 foreach 循环,即使它自动适用于任何数组长度,并且对我想要创建的每个数组混合都这样做。

我还想避免通过迭代第一个数组、组合第二个数组中的项、然后以某种方式在此过滤器段中执行总组合来创建一些结果数组,最后可能需要一个 flatten 指令。对于我需要的东西,这似乎是太多的步骤,并且可以更简洁地表示。可能是* 运算符?

我开始认为第二种方法是我需要做的,因为我可能不想“乘以​​”这些术语,而是创建一个新数组或对象以在处理其余任务时使用。

我的问题开始听起来像是在问如何在 jq 中使用过滤器和仅数据元素输入双 foreach 循环,而不是实际的 foreach 循环?

在我的示例中,我基本上想使用 2 个数组,每个数组都包含一对用于枚举状态的术语,以创建一个结果数组,使我可以遍历总共 4 个案例。这类似于组合的计算方式。

有人知道我在说什么吗? :)

【问题讨论】:

    标签: arrays json operators jq cartesian-product


    【解决方案1】:

    也许使用多个[] 迭代器时形成的隐式笛卡尔积将帮助您表达您的问题。例如,以下过滤器计算 a1a2 的乘积,而无需显式循环:

    def a1: [1,2];
    def a2: [3,4];  
    [ a1[] * a2[] ] | add
    

    给出结果21。使用字符串插值更清楚地显示了操作。用上面的a1a2

    [ "(\(a1[]) * \(a2[]))" ] | join("+")
    

    产生

    (1 * 3)+(2 * 3)+(1 * 4)+(2 * 4)
    

    您还可以使用对象构造函数形成对象集合。例如

    [ {x:a1[], y:a2[]} ]
    

    生产

    [
      { "x": 1, "y": 3 },
      { "x": 1, "y": 4 },
      { "x": 2, "y": 3 },
      { "x": 2, "y": 4 }
    ]
    

    使用这种方法,您需要决定如何组合对象。

    【讨论】:

      【解决方案2】:

      听起来您对外部产品很感兴趣。无论如何,这里有一个 outer/2 的定义,用于形成两个数组的外积:

      def outer(a; b): [a[] as $x | b[] as $y | [$x, $y]];
      

      例子:

      outer([1,2]; [3,4])
      

      产量:

       [[[1,3],[1,4]],[[2,3],[2,4]]]
      

      外(a;b;f)

      您可能想要使用这个变体(例如,它类似于 R 中的 outer(A, B, f)):

      def outer(a; b; f):
        [a[] as $x | b[] as $y | [$x, $y] | f];
      

      例如:

      def times: reduce .[] as $x (1;.*$x);
      
      outer([1,2];[3,4]; times)
      

      产生普通的外产品:

      [[3,4],[6,8]]
      

      【讨论】:

        【解决方案3】:

        我刚刚尝试了一个奇怪的早晨顿悟,并给了我可以接受的结果。

        我看到已经有其他答案了,我可能会接受仅基于内容的答案之一,因为它们似乎更简洁和描述性更强,尤其是具有数学和编程背景的人。我希望我能接受不止一个!

        我仍然会将我的jq 表达式添加到组合中,因为它显示的术语略有不同,这可能代表我想要但之前不清楚的算法,并且在完整的jq 命令调用中这样做:

        ⋊> ~ jq -cn '["one", "two"] as $num | ["a", "b"] as $let | [($num[] | [.]) + ($let[] | [.])]'                                                                                                       10:01:42
        [["one","a"],["two","a"],["one","b"],["two","b"]]
        

        【讨论】:

        • outer( ["one", "two"]; ["a", "b"]) 产生你说你想要的 FOIL 结果:[["one","a"],["one","b"],["two","a"],["two","b"]]
        猜你喜欢
        • 2023-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-23
        • 1970-01-01
        • 1970-01-01
        • 2020-05-16
        • 1970-01-01
        相关资源
        最近更新 更多