我有两个包含物品价格的数组:
[{"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
要求“如果价格尚未更新,则应删除该条目”。似乎与示例不一致,因此以下假设示例是明确的。
首先,一个用于生成(快速)查找表的小辅助函数:
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 )
结果如下。