JSON визначає масив так:
Масив - це впорядкована колекція значень. Масив починається з лівої квадратної дужки
[і закінчується правою квадратною дужкою]. Значення розділяються комою,.
Масиви можуть містити нуль або більше значень JSON будь-якого типу. Елементи масиву не обовʼязково мають бути одного типу.
Щоб зібрати елементи в масив, використовуємо дужки.
[1, 2, 3]
Елементи потоку можна зібрати в масив, узявши його в дужки.
range(5) # => a stream of 5 numbers
[range(5)] # => the array [0, 1, 2, 3, 4]
Функція length повертає кількість елементів у масиві.
Індексація в масиві починається з нуля.
Щоб дістати елемент із масиву, використовуємо вираз із дужками:
.[2] повертає третій елемент.
Відʼємні індекси відраховуються від кінця масиву:
.[-1] повертає останній елемент, а .[-2] - передостанній.
Зріз - це підпослідовність масиву.
.[10:15] повертає 5 елементів, починаючи з індексу 10; кінцевий індекс не включається.
Є кілька зручних функцій:
first повертає перший елемент.last повертає останній елемент.nth(n) повертає елемент за індексом n.Бувають випадки, коли потрібно отримати елементи масиву окремим потоком.
Для цього використовуємо .[].
Припустімо, нам потрібен потік довжин рядків тексту (англ. string) у масиві.
["a", "be", "cat", "door"] | length # => 4 -- the number of elements in the array
["a", "be", "cat", "door"] | .[] | length # => 1, 2, 3, 4 -- the lengths of each element
Порожні дужки можна поставити поряд із попереднім виразом, пропустивши конвеєр.
["a", "be", "cat", "door"][] | length # => 1, 2, 3, 4 -- the lengths of each element
# ........................^^
Щоб зʼєднати масиви, використовуємо +.
[1, 2, 3] + [4, 5] # => [1, 2, 3, 4, 5]
Оператор - вилучає з лівого масиву елементи, що є в правому масиві.
[range(10)] - [2, 4, 6] # => [0, 1, 3, 5, 7, 8, 9]
jq надає багато функцій для типових завдань ітерації:
map(expr) повертає новий масив, у якому expr застосовується по черзі до кожного елемента.
[1, 2, 3] | map(. * 10) # => [10, 20, 30]
select(expr) - це функція, яка застосовує expr до одного значення;
якщо результат виразу - правда, повертається це значення;
якщо результат - неправда, повертається нічого, не null, а справді нічого.
Щоб застосувати це до масиву, поєднуємо select із 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) повертають булеве значення (англ. Boolean) залежно від того, чи хоч один, чи всі елементи масиву задовольняють умову.
[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
Перевірити, чи містить масив елемент, можна за допомогою index.
Ця функція повертає індекс заданого елемента, якщо він є в масиві;
інакше функція повертає null.
["carrots", "beef", "potatoes"] | index("beef") # => 1
["carrots", "beef", "potatoes"] | index("bees") # => null
Є обернена функція під назвою IN (так, великими літерами).
Особливість IN у тому, що вона приймає не масив, а потік.
"beef" | IN(["carrots", "beef", "potatoes"][]) # => true
"bees" | IN(["carrots", "beef", "potatoes"][]) # => false
У Ruby є зручний метод each_with_index, який поєднує значення елемента з його індексом.
У Python для цього є enumerate.
У jq є щось схоже під назвою to_entries.
Він перетворює масив на масив обʼєктів {key: index, value: value}.
[11, 22, 33, 44] | to_entries
# => [{key: 0, value: 11}, {key: 1, value: 22}, {key: 2, value: 33}, {key: 3, value: 44}]
sort і sort_by
group_by
min, max, min_by, max_by
unique, unique_by
flatten