现在我有一个json
[
{
"city": "SH",
"age": 0,
"count": 1
},
{
"city": "SH",
"age": 20,
"count": 1
},
{
"city": "SH",
"age": 40,
"count": 1
},
{
"city": "BJ",
"age": 20,
"count": 2
},
{
"city": "BJ",
"age": 30,
"count": 1
}
]
现在我想得到每个年龄段的计数数组用于某些数据可视化目的(参见demo)。 e.g
# age data: [shCount, bjCount]
age: 0, data:[1, 0]
age: 20, data: [1, 2]
age: 30, data: [0, 1]
age: 40, data: [1, 0]
如果城市没有年龄,请给出默认值0.但是如果城市没有年龄,它将没有相关的json对象。
所以我不能只使用下面的shell来获取每个年龄的计数数组,例如
# without BJ value
➜ ~ jq -c '.[] | select(.age==0) | [.city, .count]' foo.json
["SH",1]
➜ ~ jq -c '.[] | select(.age==20) | [.city, .count]' foo.json
["SH",1]
["BJ",2]
因此,如果年龄为0,如何指定默认值0到BJ
?
答案 0 :(得分:2)
For clarity, a helper function for merging same-age records is useful. This is where the default values are defined:
def merge:
reduce .[] as $x ([0,0];
if $x.city == "SH" then .[0] = $x.count else .[1] = $x.count end);
Next, we have only to group records by age:
group_by(.age)
| map( {age: .[0].age, data: merge} )
Invocation:
jq -c -f program.jq input.json
Result:
[{"age":0,"data":[1,0]},{"age":20,"data":[1,2]},{"age":30,"data":[0,1]},{"age":40,"data":[1,0]}]
You can then format the result in whichever way you want.
答案 1 :(得分:0)
如果事先不知道相关的城市名称,那么如果城市名称是字符串,则以下方法有很多建议:
# Merge records having the same age
def merge:
reduce .[] as $x ({}; . + ($x | { (.city) : .count}) );
# Create an object holding the default values:
def zeros:
map( {(tostring): 0} ) | add;
group_by(.age)
| map( {age: .[0].age, data: merge} )
| (map(.data) | add | keys | zeros) as $zeros
| map( .data = $zeros + .data )
上面的输出是具有以下形式的对象数组: {“age”:_,“data”:CITIES}
e.g。
{
"age": 40,
"data": {
"BJ": 0,
"SH": 1
}
}
现在很容易将CITIES转换为所需的格式。