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。
I would like to use JQ to tell me how many students achieved a score > x, for each test.
上面的输入,x = 50,则输出:
Thus for the above input and x = 50, the output:
{testId: '1' numStudents:1}
{testId: '2' numStudents:2}
{testId: '3' numStudents:0}
我能够生成所有在每次考试中达到50分以上的学生的列表,
I am able to generate a list of all students who achieved > 50 on each test with
{testId, studentId: .studentId[]?} | select(.studentId.score>50)
此命令创建一个对象列表,其中每个对象都包含testId ,studentId和score,所有分数均大于50。但是,我不知道如何将这些结果重新组合到所需的输出中。
This command creates a list of objects where each object contains testId, studentId and score, where all scores are greater than 50. However I do not know how to recombine these results into the output I want.
推荐答案
以下内容假设输入包含有效的JSON对象流。
The following assumes the input consists of a stream of valid JSON objects.
一种方法是使用 add
:
$ jq '{testId, numStudents: ([select(.studentId[].score > 50) | 1] | add // 0)}'
使用给定的输入(已进行更正) ,输出为:
With the given input (after corrections have been made), the output would be:
{
testId: 1,
numStudents :1
}
{
testId: 2,
numStudents:2
}
{
testId : 3,
numStudents:0
}
使用 length
,例如
{testId,
numStudents: ([select(.studentId[].score > 50) ] | length)}
但是,如果您不介意添加'def',则最好的解决方案(例如,因为它不涉及中间数组的构造)将遵循以下几行:
However, if you don't mind adding a 'def', then the best solution (e.g. because it does not involve construction of an intermediate array) would be along the following lines:
def count(s): reduce s as $i (0; .+1);
{testId, numStudents: count(select(.studentId[].score > 50))}
这篇关于jq:计算满足条件的嵌套对象的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!