Learning Clojure Part 3: Data Structures

Pavel Polívka - Jan 6 '21 - - Dev Community

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
Enter fullscreen mode Exit fullscreen mode

Strings are represented by double-quotes. And only by them. Single quotes will not be considered strings.

"Darth Vader"
"\"You shall not pass\""
Enter fullscreen mode Exit fullscreen mode

Maps

Maps are similar to Maps in Java, Dictionaries in Python, etc..

An empty map would be defined like this:

{}
Enter fullscreen mode Exit fullscreen mode

Values would be defined like so:

{:title "Darth" :name "Vader"}
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

You can provide default value here.

(:place {:title "Darth" :name "Vader"} "Death Star")
;=> "Death Star"
Enter fullscreen mode Exit fullscreen mode

You can use strings as keys if needed tho.

Here we use a string key with the plus function.

{"key" +}
Enter fullscreen mode Exit fullscreen mode

To get this value you can use get function.

(get {"a" 0 "b" 1} "a")
;=> 0
Enter fullscreen mode Exit fullscreen mode

Maps can be nested:

{:name {:first "Anakin" :last "Skywalker"}}
Enter fullscreen mode Exit fullscreen mode

To get values in those you can use get-in expression.

(get-in {:name {:first "Anakin" :last "Skywalker"}} [:name :last])
;=> "Skywalker"
Enter fullscreen mode Exit fullscreen mode

You can also use the hash-map function to create a map.

(hash-map :a 0 :b 1)
;=> {:b 1, :a 0}
Enter fullscreen mode Exit fullscreen mode

Vectors

Vectors are similar to arrays. It's a 0-indexer collection.

The literal for vectors is:

[42 43 44]
Enter fullscreen mode Exit fullscreen mode

We can use get function to retrieve values:

(get [42 43 44] 0)
;=> 42

(get ["vector" "of" "strings"] 1)
;=> "of"
Enter fullscreen mode Exit fullscreen mode

We can also use vector expression to init a vector.

(vector 1 2 3 4 5)
Enter fullscreen mode Exit fullscreen mode

And use conj to add elements at the end of the vector.

(conj [1 2 3] 4)
;=> [1 2 3 4]
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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"}
Enter fullscreen mode Exit fullscreen mode

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"}
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

We can use contains? to check whenever the set has the value.

(contains? #{1 2} 1)
;=> true

(contains? #{1 2} 3)
;=> false
Enter fullscreen mode Exit fullscreen mode

And we can use get to get a value.

(get #{1 2} 1)
;=> 1

(get #{1 2} 3)
;=> nil
Enter fullscreen mode Exit fullscreen mode

You can follow me on Twitter to get more content like this.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .