JSON 将数组定义为:
数组是有序的值集合。 数组以左方括号
[开头,以右方括号]结尾。 值之间用逗号,分隔。
数组可以包含零个或多个_任意类型_的 JSON 值。 数组元素不必都是同一类型。
用方括号把元素收集到数组里。
[1, 2, 3]
把_流_用方括号括起来,就能把它的元素捕获成一个数组。
range(5) # => a stream of 5 numbers
[range(5)] # => the array [0, 1, 2, 3, 4]
length函数返回数组中元素的个数。
数组下标从 0 开始计数。
用方括号表达式从数组中取出元素:.[2]获取第三个元素。
负数下标从数组末尾往前计数:.[-1]获取最后一个元素,.[-2]获取倒数第二个元素。
切片是数组的一个子序列。.[10:15]从下标 10 开始返回 5 个元素,结束下标_不包含_在内。
还有一些便捷函数:
first获取第一个元素。last获取最后一个元素。nth(n)获取下标n处的元素。jq提供了许多函数来满足常见的迭代需求:
map(expr)返回一个新数组,把expr依次应用到每个元素上。
[1, 2, 3] | map(. * 10) # => [10, 20, 30]
select(expr)是一个函数,会把expr应用到一个_单个值_上;如果表达式的结果为 true,就返回这个值;如果结果为 false,则_什么都不返回_,不是null,而是真的什么都没有。
要把它应用到一个数组上,可以配合map使用。
[range(10)] | map(select(. % 2 == 0)) # => [0, 2, 4, 6, 8]
另一种做法是把select应用到_流_上,再收集结果。
[range(10) | select(. % 2 == 0)] # => [0, 2, 4, 6, 8]
any(condition)和all(condition)返回一个布尔值,表示数组中是否有任一元素满足条件,或是否所有元素都满足条件。
[1, 2, 3, 4] | any(. > 4) # false
[1, 2, 3, 4] | any(. >= 4) # true
[1, 2, 3, 4] | all(. >= 4) # false
[1, 2, 3, 4] | all(. <= 4) # true
你是一名热衷观鸟的人,一直在记录过去 7 天里有多少只鸟造访了你的花园。
你有 5 个任务,它们都与造访你花园的鸟的数量有关。
你用 JSON 格式记录鸟的数量。 一个“main”数组里存放着一周又一周的计数数组。 每一周的计数都是一个由 7 个整数组成的数组,一周中的每一天对应一个数字。 新的一周总是追加在 main 数组的末尾。 实现一个过滤器,返回上周的计数。
$ cat bird-counting-data.json
[
...,
[0, 2, 5, 3, 7, 8, 4],
[4, 5, 9, 10, 9, 4, 3]
]
$ jq -f bird-count.jq < bird-counting-data.json
{
"last_week": [0, 2, 5, 3, 7, 8, 4],
...
实现一个过滤器,返回昨天有多少只鸟造访了你的花园。 鸟的数量按天排列,第一个元素是最早一天的计数,最后一个元素是今天的计数。
$ jq -f bird-count.jq < bird-counting-data.json
{
...
"yesterday": 4,
...
实现一个过滤器,返回本周造访你花园的鸟的总数。
$ jq -f bird-count.jq < bird-counting-data.json
{
...
"total": 44,
...
有些日子比其他日子更忙。 只要一天里有 5 只或更多的鸟造访了你的花园,这一天就算忙碌。 实现一个过滤器,返回本周忙碌的天数。
$ jq -f bird-count.jq < bird-counting-data.json
{
...
"busy_days": 4,
...
实现一个过滤器:如果本周有任何一天没有鸟造访花园,就返回true;否则返回false。
$ jq -f bird-count.jq < bird-counting-data.json
{
...
"has_day_without_birds": false
}