Ма

Масиви у jq

5 вправ

Про концепцію Масиви

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

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Масиви

Практика заблокована

Розблокуйте ще 8 вправ, щоб практикувати концепцію Масиви