我不是专家jq用户,我现在尝试了很多不同的解决方案来解决我的问题。 我有一些属于特定版本的数据系列,我想要计算它们之间的差异。基础数据将始终是一个数组,其中包含两个包含数据系列值的元素。每个系列中的值的数量可以变化,即“valX”值的数量不是恒定的。 结果应该给出所有值“ver1” - “ver2”。
下面给出的结果数据是我希望得到最终结果的一个例子。如果缺少值为“0”,即1.20 => 1.2并且缺少前导零,即0.01 => .01,这没问题。
示例JSON源数据:
[
{
"version": "ver1",
"series": [
{
"id": "name1",
"val1": "0.77",
"val2": "1.34",
"val3": "7.89",
"val4": "6.00"
},
{
"id": "name2",
"val1": "0.34",
"val2": "1.00",
"val3": "12.15"
}
]
},
{
"version": "ver2",
"series": [
{
"id": "name1",
"val1": "0.35",
"val2": "2.34",
"val3": "6.50",
"val4": "6.01"
},
{
"id": "name2",
"val1": "2.54",
"val2": "0.55",
"val3": "13.20"
}
]
}
]
我想要一个像这样或类似的结果:
[
{
"id": "name1",
"val1": "-0.42",
"val2": "1.00",
"val3": "-1.39",
"val4": "0.01"
},
{
"id": "name2",
"val1": "-2.20",
"val2": "-0.45",
"val3": "1.05"
}
]
任何知识可以帮助我或者至少让我朝着正确的方向前进?
答案 0 :(得分:0)
首先,请在您的示例中修复JSON。
其次,放心jq非常适合这项任务,但它会 需要对jq有所了解才能设计出完整的解决方案 问题。
自问题陈述
目前有点不明确,因为SO不是
一个免费的编程服务,我将专注于此
需要的关键功能,我需要找到它
具有相同id
的两个对象之间的“差异”
其他键是数字字符串。
让我们从两个对象开始:
def s1: {
"id": "name1",
"val1": "0.77",
"val2": "1.34",
"val3": "7.89",
"val4": "6.00"
};
def s2: {
"id": "name1",
"val1": "0.35",
"val2": "2.34",
"val3": "6.50",
"val4": "6.01"
};
这里的难点实际上是数字舍入,由内部函数round(n)
处理:
# $a - $b
def minus($a; $b):
def round(n):
(if . < 0 then -1 else 1 end) as $s
| $s*10*.*n
| if (floor % 10) > 4 then (.+5) else . end
| ./10 | floor/n | .*$s;
def m($k): ($a[$k]|tonumber) - ($b[$k]|tonumber) | round(100);
reduce ($a|keys_unsorted[]) as $k ({};
if $k == "id" then .id = $a["id"]
else .[$k] = m($k)
end);
minus(s2; s1)
(如果你真的想要两个数字之间的区别
要成为一个字符串,只需添加一个对tostring
的调用。)
{
"id": "name1",
"val1": -0.42,
"val2": 1,
"val3": -1.39,
"val4": 0.01
}
以下调用minus/2
会在给出提供的样本数据时(在更正后)产生如下所示的结果:
map(.series) | transpose | map(minus(.[1]; .[0]))
结果:
[
{
"id": "name1",
"val1": -0.42,
"val2": 1,
"val3": -1.39,
"val4": 0.01
},
{
"id": "name2",
"val1": 2.2,
"val2": -0.45,
"val3": 1.05
}
]
...取决于你。这取决于你想要多么谨慎 匹配“id”值,处理边缘情况等。