In part three of our Clojure learning journey, we will go over Data Structures.
Out of the box, Clojure has a lot of structures that we will need most of the times. All of them are immutable. That means you cannot change them in place.
Data types
Clojure has great support for numerical values. It can support integers, floats, rotios, etc...
42
4.2
4/2
Strings are represented by double-quotes. And only by them. Single quotes will not be considered strings.
"Darth Vader"
"\"You shall not pass\""
Maps
Maps are similar to Maps in Java, Dictionaries in Python, etc..
An empty map would be defined like this:
{}
Values would be defined like so:
{:title "Darth" :name "Vader"}
The :title
and :name
are keywords. They are primarily used as keys in maps. But can be used as functions to lookup the value.
(:title {:title "Darth" :name "Vader"})
;=> "Darth"
You can provide default value here.
(:place {:title "Darth" :name "Vader"} "Death Star")
;=> "Death Star"
You can use strings as keys if needed tho.
Here we use a string key with the plus function.
{"key" +}
To get this value you can use get
function.
(get {"a" 0 "b" 1} "a")
;=> 0
Maps can be nested:
{:name {:first "Anakin" :last "Skywalker"}}
To get values in those you can use get-in
expression.
(get-in {:name {:first "Anakin" :last "Skywalker"}} [:name :last])
;=> "Skywalker"
You can also use the hash-map
function to create a map.
(hash-map :a 0 :b 1)
;=> {:b 1, :a 0}
Vectors
Vectors are similar to arrays. It's a 0-indexer collection.
The literal for vectors is:
[42 43 44]
We can use get function to retrieve values:
(get [42 43 44] 0)
;=> 42
(get ["vector" "of" "strings"] 1)
;=> "of"
We can also use vector
expression to init a vector.
(vector 1 2 3 4 5)
And use conj
to add elements at the end of the vector.
(conj [1 2 3] 4)
;=> [1 2 3 4]
Lists
Lists are very similar to vectors, there are some differences tho. You cannot retrieve an element from a list using get
but nth
(slower as it will go over all the elements) and conj
add at the beginning of the collection.
'(1 2 3 4)
;=> (1 2 3 4)
(nth '(1 2 3 4) 0)
;=> 1
(conj '(1 2 3 4) 5)
;=> (5 1 2 3 4)
So when we should use what? The best rule we can find is that when we want to easily add to the beginning we should use a list.
Sets
Sets are collections of unique values. We can use literals or a hash-set
functions.
#{"Darth Vader" "Yoda" "Anakin Skywalker"}
(hash-set "Darth Vader" "Yoda" "Anakin Skywalker" "Yoda")
;=> #{"Anakin Skywalker" "Yoda" "Darth Vader"}
See above that when we have multiple instances of one value, the second one is automatically removed.
We can add values to set by conj
, when duplicated value is added it will not be.
(conj #{"a" "b"} "c")
;=> #{"a" "b" "c"}
(conj #{"a" "b" "c"} "c")
;=> #{"a" "b" "c"}
We can also convert vectors or lists to sets by using the set
function.
(set [1 1 2 2 3 3 4 4])
;=> #{1 4 3 2}
We can use contains?
to check whenever the set has the value.
(contains? #{1 2} 1)
;=> true
(contains? #{1 2} 3)
;=> false
And we can use get
to get a value.
(get #{1 2} 1)
;=> 1
(get #{1 2} 3)
;=> nil
You can follow me on Twitter to get more content like this.
Top comments (0)