向量
向量用方括號表示:
[]
;;=> []
[:foo]
;;=> [:foo]
[:foo :bar]
;;=> [:foo :bar]
[1 (+ 1 1) 3]
;;=> [1 2 3]
另外,使用文字語法,你還可以使用 vector
函式構造向量:
(vector)
;;=> []
(vector :foo)
;;=> [:foo]
(vector :foo :bar)
;;=> [:foo :bar]
(vector 1 (+ 1 1) 3)
;;=> [1 2 3]
你可以使用 vector?
謂詞測試某些內容是否為向量 :
(vector? [])
;;=> true
(vector? [:foo :bar])
;;=> true
(vector? nil)
;;=> false
(vector? 42)
;;=> false
(vector? :foo)
;;=> false
conj
將元素新增到向量的末尾:
(conj [] :foo)
;;=> [:foo]
(conj (conj [] :foo) :bar)
;;=> [:foo :bar]
(conj [] :foo :bar)
;;=> [:foo :bar]
count
以恆定時間返回專案數:
(count [])
;;=> 0
(count (conj [] :foo))
;;=> 1
(count [:foo :bar])
;;=> 2
你可以使用 peek
獲取向量的最後一個元素 :
(peek [])
;;=> nil
(peek [:foo])
;;=> :foo
(peek [:foo :bar])
;;=> :bar
你可以使用 pop
獲得一個沒有最後一個元素的新向量 :
(pop [:foo])
;;=> []
(pop [:foo :bar])
;;=> [:foo]
請注意,如果你嘗試彈出一個空向量,你將獲得一個 IllegalStateException
:
(pop [])
;; java.lang.IllegalStateException: Can't pop empty vector
與列表不同,向量被索引。你可以使用 get
在常量時間內通過索引獲取向量的元素 :
(get [:foo :bar] 0)
;;=> :foo
(get [:foo :bar] 1)
;;=> :bar
(get [:foo :bar] -1)
;;=> nil
(get [:foo :bar] 2)
;;=> nil
另外,向量本身是獲取索引並在該索引處返回元素的函式:
([:foo :bar] 0)
;;=> :foo
([:foo :bar] 1)
;;=> :bar
但是,如果你呼叫一個索引無效的向量,你將得到一個 IndexOutOfBoundsException
而不是 nil
:
([:foo :bar] -1)
;; java.lang.IndexOutOfBoundsException:
([:foo :bar] 2)
;; java.lang.IndexOutOfBoundsException:
你可以使用 assoc
在特定索引處獲取具有不同值的新向量 :
(assoc [:foo :bar] 0 42)
;;=> [42 :bar]
(assoc [:foo :bar] 1 42)
;;=> [:foo 42]
如果傳遞的索引等於向量的 count
,Clojure 將新增元素,就像使用了 conj
一樣。但是,如果你傳遞一個負數或大於 count
的索引,你將得到一個 IndexOutOfBoundsException
:
(assoc [:foo :bar] 2 42)
;;=> [:foo :bar 42]
(assoc [:foo :bar] -1 42)
;; java.lang.IndexOutOfBoundsException:
(assoc [:foo :bar] 3 42)
;; java.lang.IndexOutOfBoundsException:
你可以使用 seq
獲取向量中的一系列專案:
(seq [])
;;=> nil
(seq [:foo])
;;=> (:foo)
(seq [:foo :bar])
;;=> (:foo :bar)
由於向量被索引,你還可以使用 rseq
獲得向量項的反轉序列 :
(rseq [])
;;=> nil
(rseq [:foo])
;;=> (:foo)
(rseq [:foo :bar])
;;=> (:bar :foo)
請注意,儘管所有列表都是序列,並且序列的顯示方式與列表相同,但並非所有序列都是列表!
'(:foo :bar)
;;=> (:foo :bar)
(seq [:foo :bar])
;;=> (:foo :bar)
(list? '(:foo :bar))
;;=> true
(list? (seq [:foo :bar]))
;;=> false
(list? (rseq [:foo :bar]))
;;=> false