We already learned how to use lists and the importance of this data structure in Clojure in the previous post. Now we gonna learn another important data structure: Vector.
What are vectors?
Vectors as lists are immutable persistent data collections that can hold any value. They can be created using the vec function passing a collection of values or passing the values directly between square brackets.
;; (vec collection)
(vec '("Red" "Green" "Blue"))
;; returns => ["Red" "Green" "Blue"]
["Gold" "Silver" "Crystal"]
;; returns => ["Gold" "Silver" "Crystal"]
Vectors vs Lists
Both vectors and lists are collections of data, but they differ a lot in how each one of them works. The first main difference you probably notice between them is while lists are written using parenthesis, vectors are written using square brackets.
'("List" 1 2 3)
;; returns => ("List" 1 2 3)
["Vector" 1 2 3]
;; returns => ["Vector" 1 2 3]
Looking now they seem to do the same thing, but the data structure underlying these collections are different and have a lot of differences in practical use.
(class '("List" 1 2 3))
;; returns => clojure.lang.PersistentList
["Vector" 1 2 3]
;; returns => clojure.lang.PersistentVector
While lists, as we seem, are noncontinuous values in memory that hold a value and a reference to the next value, vectors are values that are continuous in memory so the elements are indexed and can be fast accessed by their index position using the function nth.
;; (nth collection index)
(nth ["Charmander" "Pikachu" "Buterfree"] 0)
;; returns => "Charmander"
(nth ["Charmander" "Pikachu" "Buterfree"] 2)
;; returns => "Buterfree"
Image: "Vectors representation" made by the author is copyleft material under unlicense.
Adding values
Another great difference between them is when we use the conj function to add an element to the collection because the function will add the element in faster way to the collection:
- In lists is faster to add a new element to the beginning since that to do it it's not necessary to go through the entire list to add it in another position.
- In vectors, the element is added in the last position since it just gets the last index and adds it after.
Image: "Conj vector vs list" made by the author is copyleft material under unlicense.
We can see this with some examples:
(conj '("Charmander" "Pikachu" "Buterfree") "Zubat")
;; returns => ("Zubat" "Charmander" "Pikachu" "Buterfree")
(conj ["Charmander" "Pikachu" "Buterfree"] "Zubat")
;; returns => ["Charmander" "Pikachu" "Buterfree" "Zubat"]
Vectors and Lists
We can use the nth to efficiently access a value by its position, but we can also use any of the functions we see in lists before as well. They can be used to iterate over the vector as we can do with lists and other collections.
first
The first function returns the element at the beginning of the vector.
(first ["Brock" "Misty" "Lt. Surge" "Erika"])
;; returns => "Brock"
second
The second function returns the second element of the vector.
(second ["Brock" "Misty" "Lt. Surge" "Erika"])
;; returns => "Misty"
last
The last function returns the element at the end of the vector.
(last ["Brock" "Misty" "Lt. Surge" "Erika"])
;; returns => "Erika"
rest
The rest functions return the vector as a list without the first element.
(rest ["Brock" "Misty" "Lt. Surge" "Erika"])
;; returns => ("Misty" "Lt. Surge" "Erika")
When we should use lists over vectors?
If you intend to add and retrieve values at the beginning or at the end of the collection all the time, then a list will be far more efficient than a vector.
On another side, if you need to add and retrieve values in the middle or in indexed positions then a vector will be far more efficient than a list.
You should consider it when choosing which of them you will use, as general advice usually vectors are more frequently used than lists in most cases.
See you in the next part!
Having 2 different collections that look so similar and work so different can be a little confusing at begging especially if you don't know how these data structures are made but don't worry this will become natural as you get used to Clojure.
Top comments (0)