假设我有:[[1,2], [3,9], [4,2], [], []]
我想知道要获取的脚本:
不是非空的嵌套列表的数量。即想得到:[3,2]
包含或不包含数字3的嵌套列表的数量。即,要获取:[1,4]
其元素的总和不小于4
的嵌套列表的数量。即想得到:[3,2]
即嵌套数据分区的基本示例。
答案 0 :(得分:1)
由于stackoverflow.com不是编码服务,因此我将对第一个问题的回答仅限于此,希望它可以说服您学习jq是值得的。
让我们首先完善有关列表计数的问题
“不为空”将强调答案中的第一个数字应与空列表的数量(2)相对应,而第二个数字应与其余的列表(3)相对应。也就是说,所需答案应为[2,3]
。
下一步可能是询问是否可以使用group_by
。如果顺序无关紧要,我们可以简单地写:
group_by(length==0) | map(length)
这返回[3,2]
,这不是我们想要的。现在值得检查有关group_by
应该做什么的文档。在查看https://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions上的详细信息时,
我们看到,group_by
确实确实按分组值排序。
自从jq false < true
开始,我们可以通过编写以下内容来修正我们的首次尝试:
group_by(length > 0) | map(length)
这很好,但是由于group_by
所做的工作量很大,而我们真正需要的只是一种计数方法,因此很显然,我们应该能够提出一个更有效(并且希望更少不透明)的解决方案。
从根本上讲,问题可以归结为计数,因此让我们定义一个通用的tabulate
过滤器以产生不同字符串值的计数。这是一个足以满足当前目的的定义:
# Produce a JSON object recording the counts of distinct
# values in the given stream, which is assumed to consist
# solely of strings.
def tabulate(stream):
reduce stream as $s ({}; .[$s] += 1);
现在只需两行就可以写下一个有效的解决方案:
tabulate(.[] | length==0 | tostring )
| [.["true", "false"]]
QED
上面名为tabulate
的函数有时称为bow
(用于“单词袋”)。在某些方面,这将是一个更好的名称,尤其是将tabulate
保留为适用于任意流的类似功能是很有意义的。