[1 2 3]
Clojure collections "collect" values into compound values. There are four key Clojure collection types: vectors, lists, sets, and maps. Of those four collection types, vectors and lists are ordered.
Vectors are an indexed, sequential data structure. Vectors are represented with [ ]
like this:
[1 2 3]
"Indexed" means that elements of a vector can be retrieved by index. In Clojure (as in Java), indexes start at 0, not 1. Use the get
function to retrieve an element at an index:
user=> (get ["abc" false 99] 0)
"abc"
user=> (get ["abc" false 99] 1)
false
Calling get with an invalid index returns nil
:
user=> (get ["abc" false 99] 14)
nil
In addition to the literal [ ]
syntax, Clojure vectors can be created with the vector
function:
user=> (vector 1 2 3)
[1 2 3]
Elements are added to a vector with conj
(short for conjoin). Elements are always added to a vector at the end:
user=> (conj [1 2 3] 4 5 6)
[1 2 3 4 5 6]
Clojure collections share important properties of simple values like strings and numbers, such as immutability and equality comparison by value.
For example, lets create a vector and modify it with conj
.
user=> (def v [1 2 3])
#'user/v
user=> (conj v 4 5 6)
[1 2 3 4 5 6]
Here conj
returned a new vector but if we examine the original vector, we see it’s unchanged:
user=> v
[1 2 3]
Any function that "changes" a collection returns a new instance. Your program will need to remember or pass along the changed instance to take advantage of it.
Lists are sequential linked lists that add new elements at the head of the list, instead of at the tail like vectors.
Because lists are evaluated by invoking the first element as a function, we must quote a list to prevent evaluation:
(def cards '(10 :ace :jack 9))
Lists are not indexed so they must be walked using first
and rest
.
user=> (first cards)
10
user=> (rest cards)
'(:ace :jack 9)