Working with Clojure collections is a pleasure. Yet, sometimes one may run into unexpected behaviors. In this series, we take a look at the most simple Clojure data structures.
Vectors are sequential collections with constant time random access capability. One can also view vectors as integer to element mappings. Examples:
You can acces an element on the nth index with the
get function or the
nth function. Be aware that when a given index is not found the
get function returns
nil while the
nth function throws an
IndexOutOfBoundsException. You can specify a default value as a third argument that is returned when the index is not found.
Vectors also act like functions (they implement the
clojure.lang.IFn interface). An IOOBE exception is thrown when called on an uknown index.
We can also modify an item on an index of a vector:
That’s right, one can change an item on an index of a vector just like with a map.
How is about removing an item from a vector?
You can not call
dissoc on a vector because that could not remove an item without affecting the indices of all other items after the given index. To remove an item, first you need to split the vector into two parts (calling
subvec) and then create a vector from the concatenation of the result.
You can use the
subvec function to return part of a vector.
Usage as queues
Vectors are often used as queues.
conjfunction appends a value to the end of the vector.
peekfunction returs the last item of the vector in constant time. (The
lastfunction is linear time thus much slower usually.)
popfunction drops the last item from a vector.
You can turn a vector to a sequence with the
seq function (note that
(seq ) is
rseq function returns a lazy sequence of items in the vector in reverse order. It is advised to favor
reverse because of the constant time complexity and lazyness.