我有流
{
"key": "a",
"value": 1
}
{
"key": "b",
"value": 1
}
{
"key": "c",
"value": 1
}
{
"key": "d",
"value": 1
}
{
"key": "e",
"value": 1
}
和
(true,true,false,false,true)
我想一对一地比较这两个,并且仅当对应的布尔值为true
时才打印对象。
所以我想输出
{
"key": "a",
"value": 1
}
{
"key": "b",
"value": 1
}
{
"key": "e",
"value": 1
}
我试过了(https://jqplay.org/s/GGTHEfQ9s3)
filter:
. as $input | foreach (true,true,false,false,true) as $dict ($input; select($dict))
input:
{
"key": "a",
"value": 1
}
{
"key": "b",
"value": 1
}
{
"key": "c",
"value": 1
}
{
"key": "d",
"value": 1
}
{
"key": "e",
"value": 1
}
但我得到了输出:
{"key":"a","value":1}
{"key":"a","value":1}
null
{"key":"b","value":1}
{"key":"b","value":1}
null
{"key":"c","value":1}
{"key":"c","value":1}
null
{"key":"d","value":1}
{"key":"d","value":1}
null
{"key":"e","value":1}
{"key":"e","value":1}
null
我们将不胜感激。
一种方法是以数组的形式读取流,使用transpose
来匹配它们的项,并使用select
一个来输出另一个:
jq -s '[.,[(true,true,false,false,true)]] | transpose[] | select(.[1])[0]' objects.json
演示
另一种方法是将流作为数组读取,将布尔值数组转换为条件匹配的indices
,并使用它们引用到对象数组中:
jq -s '.[[(true,true,false,false,true)] | indices(true)[]]' objects.json
演示
相同的方法,但使用nth
引用到inputs
流中需要更多的预防措施,因为流输入的连续消耗需要提供到nth
的相对距离,而不是绝对位置。可以通过使用index
和while
循环依次检查下一个true
值的位置来实现转换:
jq -n 'nth([true,true,false,false,true] | while(. != []; .[index(true) + 1:]) | index(true) | values; inputs)' objects.json
演示
也可以使用reduce
直接迭代布尔值,只使用select
任何适当的input
:
jq -n 'reduce (true,true,false,false,true) as $dict ([]; . + [input | select($dict)]) | .[]' objects.json
演示
使用foreach
的解决方案,就像您想要的那样,也需要-n
选项来避免错过第一项:
jq -n 'foreach (true,true,false,false,true) as $dict (null; input | select($dict))' objects.json
演示
不幸的是,jq的每次调用目前最多只能处理一个外部JSON流。这通常不是一个问题,除非两个流都很大,所以在这个答案中,我将重点关注一个可扩展的解决方案。事实上,无论数据流有多大,所需的计算机内存量都是微不足道的
为了简单起见,我们假设:
- demon.json是一个由json布尔值流组成的文件(即,不以逗号分隔(
- object.json是json对象流
- 流具有相同的长度
- 我们在bash或类似bash的环境中工作
然后我们可以使用:
paste -d 't' demon.json <(jq -c . objects.json) | jq -n '
foreach inputs as $boolean (null; input; select($boolean))'
因此,除了paste
和jq
的启动成本外,我们基本上只需要足够的内存来一次保存objects.json中的一个对象。这个解决方案也很快。
当然,如果objects.json已经是JSONL(json行(格式,那么就不需要对上面的jq进行第一次调用。