JQ:使用辅助阵列丰富主阵列

问题描述 投票:0回答:1

我有两个包含物品价格的数组:

[{"id":"a","p":5},{"id":"b","p":7},{"id":"c","p":8}]

[{"id":"a","p":9},{"id":"b","p":7},{"id":"d","p":4}]

我想要使​​用辅助数组中的价格来丰富主数组(如果可用)。如果价格尚未更新,则应删除该条目。因此,想要的输出是(“b”被删除,因为价格相等而且“c”保持不变):

[{"id":"a","p":5,"c":9},{"id":"c","p":8,"c":null}]

我尝试使用select但这会删除两个数组中不可用的项目:

echo '$pri' | jq -c --argjson sec '$sec' '.[]|. as {id:$id,p:$c}|{id,p,"c":($sec[]|select(.id==$id and .p!=$c).p)}'

编辑:高峰的回答让我朝着正确的方向前进。一旦它工作,我进一步改进了它。

更新后的价格始终是一个以未分类方式包含所有项目的数组。当没有真正的更新时,我想避免光盘写入。

因此,我已经以字典格式保存了最后的价格响应,如:

wget ... | jq -c 'reduce .[] as $x ({}; .[$x|.id|tostring]=$x)' >lastprices

此步骤转换输入数组

{"id":28460,"price":"1.119","time":"2018-03-05T18:33:43Z","camp":null}
{"id":11438,"price":"1.119","time":"2018-03-05T18:58:26Z","camp":null}
{"id":11627,"price":"1.119","time":"2018-03-05T18:47:45Z","camp":null}
{"id":6905,"price":"1.119","time":"2018-03-05T19:03:59Z","camp":null}

到索引排序的输出数组(字典)

{ "6905"  : { "id":6905,  "price":"1.119", "time":"2018-03-05T19:03:59Z", "camp":null },
  "11438" : { "id":11438, "price":"1.119", "time":"2018-03-05T18:58:26Z", "camp":null },
  "11627" : { "id":11627, "price":"1.119", "time":"2018-03-05T18:47:45Z", "camp":null },
  "28460" : { "id":28460, "price":"1.119", "time":"2018-03-05T18:33:43Z", "camp":null } }

在下一次迭代中,我比较了update.time != last.time并且仅保留(= select)已更新的项目:

wget ... | jq -c --argfile last lastprices '[.[]|select(.time!=$last[.id|tostring].time)]'

如果比较评估非空数组我convert it to CSV并将其附加到“数据库”(保存为JSON将需要每次重写整个数组):

echo "$COMPARISON" | jq -rc '(.[0] | keys_unsorted) as $keys | map([.[ $keys[] ]])[]|@csv'>>gasdb.csv

arrays json match jq
1个回答
0
投票

要求“如果价格尚未更新,则应删除该条目”。似乎与示例不一致,因此以下假设示例是明确的。

首先,一个用于生成(快速)查找表的小辅助函数:

def dict(f): reduce .[] as $x ({}; .[$x|f] = $x);

在下面,如在问题的文本中,$pri指的是具有旧价格的数组,并且$sec指向具有新价格的数组:

($sec|dict(.id)) as $new
| reduce $pri[] as $x ([];
    $new[$x.id] as $y
    | if ($y.p == $x.p) then .
      else . + [$x | (.c = $y.p)]
      end )

结果如下。

© www.soinside.com 2019 - 2024. All rights reserved.