jq:计算满足条件的嵌套对象值
jq: count nest object values which satisfy condition
json数据:
{testId: '1' studentId:{'s1':{score: 20} 's2':{score: 80}}}
{testId: '2' studentId:{'s1':{score: 60} 's2':{score: 70}}}
{testId: '3' studentId:{'s5':{score: 40} 's7':{score: 30}}}
...
我想用 JQ 告诉我有多少学生的分数 > x,对于每个测试。
因此对于上面的输入和x = 50,输出:
{testId: '1' numStudents:1}
{testId: '2' numStudents:2}
{testId: '3' numStudents:0}
我能够生成一个列表,其中包含在每个测试中取得 > 50 分的所有学生
{testId, studentId: .studentId[]?} | select(.studentId.score>50)
此命令创建一个对象列表,其中每个对象包含 testId、studentId 和分数,其中所有分数都大于 50。但是我不知道如何将这些结果重新组合成我想要的输出。
以下假定输入由有效 JSON 对象流组成。
一种方法是使用 add
:
$ jq '{testId, numStudents: ([select(.studentId[].score > 50) | 1] | add // 0)}'
使用给定的输入(进行更正后),输出将是:
{
"testId": "1",
"numStudents": 1
}
{
"testId": "2",
"numStudents": 2
}
{
"testId": "3",
"numStudents": 0
}
另一种方法是使用 length
,例如使用此过滤器:
{testId,
numStudents: ([select(.studentId[].score > 50) ] | length)}
但是,如果您不介意添加 'def',那么最好的解决方案(例如,因为它不涉及构建中间数组)将遵循以下几行:
def count(s): reduce s as $i (0; .+1);
{testId, numStudents: count(select(.studentId[].score > 50))}
json数据:
{testId: '1' studentId:{'s1':{score: 20} 's2':{score: 80}}}
{testId: '2' studentId:{'s1':{score: 60} 's2':{score: 70}}}
{testId: '3' studentId:{'s5':{score: 40} 's7':{score: 30}}}
...
我想用 JQ 告诉我有多少学生的分数 > x,对于每个测试。
因此对于上面的输入和x = 50,输出:
{testId: '1' numStudents:1}
{testId: '2' numStudents:2}
{testId: '3' numStudents:0}
我能够生成一个列表,其中包含在每个测试中取得 > 50 分的所有学生
{testId, studentId: .studentId[]?} | select(.studentId.score>50)
此命令创建一个对象列表,其中每个对象包含 testId、studentId 和分数,其中所有分数都大于 50。但是我不知道如何将这些结果重新组合成我想要的输出。
以下假定输入由有效 JSON 对象流组成。
一种方法是使用 add
:
$ jq '{testId, numStudents: ([select(.studentId[].score > 50) | 1] | add // 0)}'
使用给定的输入(进行更正后),输出将是:
{
"testId": "1",
"numStudents": 1
}
{
"testId": "2",
"numStudents": 2
}
{
"testId": "3",
"numStudents": 0
}
另一种方法是使用 length
,例如使用此过滤器:
{testId,
numStudents: ([select(.studentId[].score > 50) ] | length)}
但是,如果您不介意添加 'def',那么最好的解决方案(例如,因为它不涉及构建中间数组)将遵循以下几行:
def count(s): reduce s as $i (0; .+1);
{testId, numStudents: count(select(.studentId[].score > 50))}