計數
Clojure 集合會將值「收集」成複合值。Clojure 有四種主要的集合類型:向量、串列、集合和映射。在四種集合類型中,向量和串列是有序的。
向量是一種索引式的順序資料結構。向量的表示方式為 [ ],如下所示
[ ]
[1 2 3]
「索引式」表示向量的元素可以用索引來擷取。在 Clojure 中(如同在 Java 中),索引從 0 開始,而不是 1。使用 get 函式來擷取索引處的元素
get
user=> (get ["abc" false 99] 0) "abc" user=> (get ["abc" false 99] 1) false
使用無效索引呼叫 get 會傳回 nil
nil
user=> (get ["abc" false 99] 14) nil
所有 Clojure 集合都可以計數
user=> (count [1 2 3]) 3
除了文字 [ ] 語法之外,Clojure 向量也可以使用 vector 函式來建立
vector
user=> (vector 1 2 3) [1 2 3]
元素會使用 conj(連接的簡寫)加入向量中。元素總是會加入到向量的尾端
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))
串列沒有索引,因此必須使用 first 和 rest 來遍歷它們。
first
rest
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)