代码之家  ›  专栏  ›  技术社区  ›  2rs2ts

在数组元素上平均分布数字(并将余数添加到环的开头)

  •  1
  • 2rs2ts  · 技术社区  · 7 年前

    假设我有一个JSON数组,我们称之为 A :

    ["foo", "bar", "baz"]

    我有一些号码 X

    {
      "foo": 2,
      "bar": 2,
      "baz": 1,
    }
    

    这是数字5,在数组的元素之间平均分配,其余的被分配到环的开始的元素。你可以这样想,元素的价值 N 应该是 ceil(X / length(A)) 如果 index(N) < (X % length(A)) ,否则应该是 floor(X / length(A)) .

    假设 一个 定义为变量时,我如何在jq中表示它?

    我试过了 'length as $len | .[] | if index(.) < (5 % $len) then (5 / $len) + 1 else 5 / $len end' | 5 作为一个起点,但是每个元素我得到2个。

    2 回复  |  直到 7 年前
        1
  •  2
  •   chepner    7 年前

    你可以使用 transpose 函数来帮助构建此。用一个 ceil ceil($count - $i)/$n) ,其中 $count 是你分配的金额, $i $n 是列表的长度。

    注释显示了每件作品是如何在您的示例输入上工作的 ["foo", "bar", "baz"]

    def ceil(v): -(-v | floor);
    def objectify(n): {key: .[0], value: ceil(($count - .[1])/n)}; 
      # ["foo", 0] | objectify(3) -> {"key": "foo", "value", 2}
    length as $n |   # n == 3
    [., keys]    |   # [["foo", "bar", "baz"], [0,1,2]]
    [transpose[] |   # [["foo", 0], ["bar", 1], ["baz", 2]]
        objectify($n)
    ] |
    from_entries # {"foo": 2, "bar": 2, "baz": 1}
    

    没有评论。。。

    def ceil(v): -(-v | floor);
    def objectify(n): {key: .[0], value: ceil(($count - .[1])/n)};
    length as $n | [., keys] | [transpose[] | objectify($n)] | from_entries
    

    distribute.jq :

    jq --argjson count 5 -f distribute.jq tmp.json
    
        2
  •  -1
  •   2rs2ts    7 年前

    . as $arr
    | length as $len
    | [
        .[]
        | . as $i
        | {
            $(i): (
              if ($arr | index($i)) < ($x % $len) then
                ($x / $len) + 1
              else
                $x / $len
              end
              | floor
            )
          }
      ]
    | add
    

    --argjson count $X 输入数组作为输入。