陣列

陣列 在 jq

5 個練習

關於 陣列

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的元素。

轉換成元素串流

有時候我們會想逐一串流陣列中的元素。 這時就可以使用.[]。

假設我們想要取得陣列中各字串長度的串流。

["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套用到_單一值_上; 如果運算式的結果為 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
    

成員判斷

我們可以用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 個練習,就能練習 陣列