【问题标题】:remember previous json value in array记住数组中的前一个 json 值
【发布时间】:2021-10-20 04:04:19
【问题描述】:

我有一个排序的数组列表,我希望根据数组上一次迭代中 json bool 的值做出格式化决定。代码示例使用 igroup 的当前值,但我需要在 igroup=true 的第一个实例上有一个 MARK,然后所有后续 igroup=true 为 SPACE。为此,我需要知道 igroup 的先前值是什么。尝试记住 prev 值似乎是一个变量,所以我不知道如何实现这一点。

代码:

.result
| keys[] as $c
|
  (
      (.[$c].segments[0].lines | keys[]) as $l |
            [
            "line format",
            ( if .[$c].segments[0].lines[$l].igroup then "SPACE"
              else "MARK" end ),
            ( [ .[$c].segments[0].lines[$l].products[].name ] | join(",")),
            "end line format"
            ]
  ),
  ["END","0"]
| join("|")

示例数据:

{
  "result": [
    {
      "cn": "abc",
      "segments": [
        {
          "lines": [
            {
              "igroup": false,
              "products": [
                {
                  "name": "Should be MARK"
                }
              ]
            },
            {
              "igroup": false,
              "products": [
                {
                  "name": "Should be MARK"
                },
                {
                  "name": "Addon to MARK"
                }
              ]
            },
            {
              "igroup": true,
              "products": [
                {
                  "name": "Should be MARK First igroup=true BROKEN!!!"
                }
              ]
            },
            {
              "igroup": true,
              "products": [
                {
                  "name": "Should be SPACE !! After first igroup=true"
                }
              ]
            },
            {
              "igroup": true,
              "products": [
                {
                  "name": "Should be SPACE until next igroup=false"
                }
              ]
            },
            {
              "igroup": false,
              "products": [
                {
                  "name": "Should be MARK"
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "id": 1
}

输出:

"line format|MARK|Should be MARK|end line format"
"line format|MARK|Should be MARK,Addon to MARK|end line format"
"line format|SPACE|Should be MARK First igroup=true BROKEN!!!|end line format"
"line format|SPACE|Should be SPACE !! After first igroup=true|end line format"
"line format|SPACE|Should be SPACE until next igroup=false|end line format"
"line format|MARK|Should be MARK|end line format"
"END|0"

【问题讨论】:

标签: json jq


【解决方案1】:

您可以采取几种方法,减少索引,以便您可以索引到数组中以检查值。但这需要保留对原始输入的单独引用。

否则使用foreach 可以让您通过累加器跟踪之前的igroup

foreach .result[].segments[].lines[] as {$igroup,$products} (
  [null,false];    # init: pair of previous and current value
  [.[1],$igroup];  # update: update values
  [
    "line format",
    if .[0] and .[0] == $igroup then "SPACE" else "MARK" end,
    ([$products[].name] | join(",")),
    "end line format"
  ] # extract: the collection of values to output
), ["END",0] | join("|")
"line format|MARK|Should be MARK|end line format"
"line format|MARK|Should be MARK,Addon to MARK|end line format"
"line format|MARK|Should be MARK First igroup=true BROKEN!!!|end line format"
"line format|SPACE|Should be SPACE !! After first igroup=true|end line format"
"line format|SPACE|Should be SPACE until next igroup=false|end line format"
"line format|MARK|Should be MARK|end line format"
"END|0"

根据需要调整输出。

jqplay

【讨论】:

  • 示例中的第 2 行(然后是“SPACE”....)应该被删除以使其工作。
  • 是的,粘贴不好:)
【解决方案2】:

我能够自己取得一些进展,但对结果仍然不满意。我能够使用索引来检查上一个数组的值。我不喜欢 3 个深 if-then-else-end 块,但至少它有效。它的作用是允许我访问测试数据未显示的线段和线阵列中的大量其他字段。

.result
| keys[] as $c
|
  (
      (.[$c].segments[0].lines | keys[]) as $l |
            [
            ( $l ),
            ( if $l > 0
              then
              ( if .[$c].segments[0].lines[$l].igroup
                then
                 ( if .[$c].segments[0].lines[$l - 1].igroup
                    then "SPACE"
                    else "MARK" end
                 )
                else "MARK" end
              )
              else "MARK" end
            ),
            
            "line format",
            ( [ .[$c].segments[0].lines[$l].products[].name ] | join(",")),
            "end line format"
            ]
  ),
  ["END","0"]
| join("|")

我将研究上述解决方案作为替代方案。

【讨论】:

    猜你喜欢
    • 2018-05-28
    • 2021-01-24
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    • 2016-08-26
    • 2015-02-03
    相关资源
    最近更新 更多