Clojure

學習 Clojure - 順序集合

Clojure 集合會將值「收集」成複合值。Clojure 有四種主要的集合類型:向量、串列、集合和映射。在四種集合類型中,向量和串列是有序的。

向量

向量是一種索引式的順序資料結構。向量的表示方式為 [ ],如下所示

[1 2 3]

索引存取

「索引式」表示向量的元素可以用索引來擷取。在 Clojure 中(如同在 Java 中),索引從 0 開始,而不是 1。使用 get 函式來擷取索引處的元素

user=> (get ["abc" false 99] 0)
"abc"
user=> (get ["abc" false 99] 1)
false

使用無效索引呼叫 get 會傳回 nil

user=> (get ["abc" false 99] 14)
nil

計數

所有 Clojure 集合都可以計數

user=> (count [1 2 3])
3

建構

除了文字 [ ] 語法之外,Clojure 向量也可以使用 vector 函式來建立

user=> (vector 1 2 3)
[1 2 3]

新增元素

元素會使用 conj(連接的簡寫)加入向量中。元素總是會加入到向量的尾端

user=> (conj [1 2 3] 4 5 6)
[1 2 3 4 5 6]

不可變性

Clojure 集合與字串和數字等簡單值共享重要的屬性,例如不可變性和透過值進行相等性比較。

例如,讓我們建立一個向量並使用 conj 修改它。

user=> (def v [1 2 3])
#'user/v
user=> (conj v 4 5 6)
[1 2 3 4 5 6]

這裡 conj 回傳一個新的向量,但如果我們檢查原始向量,會看到它沒有改變

user=> v
[1 2 3]

任何「變更」集合的函式都會回傳一個新的執行個體。你的程式需要記住或傳遞已變更的執行個體才能利用它。

串列

串列是順序連結串列,會在串列的頭部新增新元素,而不是像向量一樣在尾部新增。

建構

由於串列是透過呼叫第一個元素作為函式來評估,因此我們必須引用串列以防止評估

(def cards '(10 :ace :jack 9))

串列沒有索引,因此必須使用 firstrest 來遍歷它們。

user=> (first cards)
10
user=> (rest cards)
'(:ace :jack 9)

新增元素

conj 可用於將元素新增到串列中,就像向量一樣。但是,conj 始終會在資料結構中可以恆定時間執行的部分新增元素。在串列的情況下,元素會新增在前面

user=> (conj cards :queen)
(:queen 10 :ace :jack 9)

堆疊存取

串列也可以使用 peek 和 pop 作為堆疊

user=> (def stack '(:a :b))
#'user/stack
user=> (peek stack)
:a
user=> (pop stack)
(:b)