A vector is denoted by square brackets:
[]
;;=> []
[:foo]
;;=> [:foo]
[:foo :bar]
;;=> [:foo :bar]
[1 (+ 1 1) 3]
;;=> [1 2 3]
In addition using to the literal syntax, you can also use the vector
function to construct a vector:
(vector)
;;=> []
(vector :foo)
;;=> [:foo]
(vector :foo :bar)
;;=> [:foo :bar]
(vector 1 (+ 1 1) 3)
;;=> [1 2 3]
You can test whether something is a vector using the vector?
predicate:
(vector? [])
;;=> true
(vector? [:foo :bar])
;;=> true
(vector? nil)
;;=> false
(vector? 42)
;;=> false
(vector? :foo)
;;=> false
conj
adds elements to the end of a vector:
(conj [] :foo)
;;=> [:foo]
(conj (conj [] :foo) :bar)
;;=> [:foo :bar]
(conj [] :foo :bar)
;;=> [:foo :bar]
count
returns the number of items, in constant time:
(count [])
;;=> 0
(count (conj [] :foo))
;;=> 1
(count [:foo :bar])
;;=> 2
You can get the last element of a vector using peek
:
(peek [])
;;=> nil
(peek [:foo])
;;=> :foo
(peek [:foo :bar])
;;=> :bar
You can get a new vector without the last element using pop
:
(pop [:foo])
;;=> []
(pop [:foo :bar])
;;=> [:foo]
Note that if you try to pop an empty vector, you'll get an IllegalStateException
:
(pop [])
;; java.lang.IllegalStateException: Can't pop empty vector
Unlike lists, vectors are indexed. You can get an element of a vector by index in "constant" time using get
:
(get [:foo :bar] 0)
;;=> :foo
(get [:foo :bar] 1)
;;=> :bar
(get [:foo :bar] -1)
;;=> nil
(get [:foo :bar] 2)
;;=> nil
In addition, vectors themselves are functions that take an index and return the element at that index:
([:foo :bar] 0)
;;=> :foo
([:foo :bar] 1)
;;=> :bar
However, if you call a vector with an invalid index, you'll get an IndexOutOfBoundsException
instead of nil
:
([:foo :bar] -1)
;; java.lang.IndexOutOfBoundsException:
([:foo :bar] 2)
;; java.lang.IndexOutOfBoundsException:
You can get a new vector with a different value at a particular index using assoc
:
(assoc [:foo :bar] 0 42)
;;=> [42 :bar]
(assoc [:foo :bar] 1 42)
;;=> [:foo 42]
If you pass an index equal to the count
of the vector, Clojure will add the element as if you had used conj
. However, if you pass an index that is negative or greater than the count
, you'll get an 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:
You can get a sequence of the items in a vector using seq
:
(seq [])
;;=> nil
(seq [:foo])
;;=> (:foo)
(seq [:foo :bar])
;;=> (:foo :bar)
Since vectors are indexed, you can also get a reversed sequence of a vector's items using rseq
:
(rseq [])
;;=> nil
(rseq [:foo])
;;=> (:foo)
(rseq [:foo :bar])
;;=> (:bar :foo)
Note that, although all lists are sequences, and sequences are displayed in the same way as lists, not all sequences are lists!
'(:foo :bar)
;;=> (:foo :bar)
(seq [:foo :bar])
;;=> (:foo :bar)
(list? '(:foo :bar))
;;=> true
(list? (seq [:foo :bar]))
;;=> false
(list? (rseq [:foo :bar]))
;;=> false