droptake

此頁面說明集合管線模式中的操作。如需更多脈絡,請閱讀

切片

傳回給定第一個和最後一個位置之間清單的子序列。

如果您想要清單的一部分,您可以取用清單的切片。根據您想要的切片,有不同的運算子由語言提供。

最通用的形式允許您切出任何範圍的元素。

ruby…
[1,2,3,4,5,6].slice(2..4)
# => [3, 4, 5]
clojure…
(subvec [1 2 3 4 5 6] 2 5)
;; => [3 4 5]

這兩個基本範例提出了幾個重點。首先,大多數語言使用從 0 開始的索引,因為程式設計師自然會用「0、1、2… 9」來數到十。

Ruby 使用包含範圍來指定切片,而 clojure 使用兩個數字,其中包含開始但排除結束。Ruby 的範圍表示法允許使用

ruby…
[1,2,3,4,5,6].slice(2...5)
# => [3, 4, 5]

我很少使用三點形式,有些程式設計師不喜歡使用它,因為「...」和「..」之間的差異非常細微。

Ruby 可以使用陣列參數來切片。

ruby…
[1,2,3,4,5,6][2..4]
# => [3, 4, 5]

此形式在管線形式中可能無法順利讀取。

Clojure 的 subvec 函數只會作用於向量,而不會作用於一般的清單。它在向量上很快(因為它們有索引),但在其他形式的 clojure 清單上不會很快,因此它僅限於操作向量有助於避免在操作使用的一般性上失去效能的驚喜。Subvec 也不符合 clojure 管線的慣例,因為集合參數不是最後一個參數,因此它無法與 ->> 搭配使用。

在 Clojure 中,你可以省略第二個參數,從列表的第一個元素切片到最後一個元素,在 Ruby 中,你可以使用範圍中的負數來實現此操作。

ruby…
[1,2,3,4,5,6].slice(2..-1)
# => [3, 4, 5, 6]
clojure…
(subvec [1 2 3 4 5 6] 2)
;; => [3 4 5 6]

Ruby 的範圍可以使用負數參數從列表的最後一個元素開始計算。

ruby…
[1,2,3,4,5,6].slice(-4..-2)
# => [3, 4, 5]

許多語言不使用一般的切片操作,而是使用單獨的取用和捨棄函數。取用會傳回第一個元素(等同於 Ruby 中的 slice(0..2))。

ruby…
[1,2,3,4,5,6].take(3)
# => [1, 2, 3]
clojure…
(take 3 [1 2 3 4 5 6])
;; => (1 2 3)

捨棄會捨棄第一個元素(等同於 Ruby 中的 slice(-3..-1))。

ruby…
[1,2,3,4,5,6].drop(3)
# => [4, 5, 6]
clojure…
(drop 3 [1 2 3 4 5 6])
;; => (4 5 6)

你可以透過串接取用和捨棄來形成一個切片。

ruby…
[1,2,3,4,5,6].take(5).drop(2)
# => [3, 4, 5]
clojure…
(drop 2 (take 5 [1 2 3 4 5 6]))
;; => (3 4 5)

請注意,這些數字對應到 Ruby 切片運算子中的非包容範圍。

取用-捨棄方法非常適合用於惰性列表,因為這兩個操作都可以完成,而無需解析整個列表。

如果你需要從列表的最後一個元素開始處理,Clojure 提供了 take-lastdrop-last

clojure…
(take-last 2 [1 2 3 4 5 6])
;; => (5 6)
(drop-last 2 [1 2 3 4 5 6])
;; => (1 2 3 4)