We will look at how data is accessed and processed in Clojure.
Clojure is a functional language. It’s data storage is primarily write once, read only.
We (almost) never modify data in-place.
Building a data structure from smaller pieces is known as construction.
;; A vector
["Ken" "CS" "Clojure"]
;; A hashmap
{:name "Ken"
:group "CS"
:likes "Clojure"}
;; A set
#{ :red :green :blue }
;; A list (note the quote)
'("Ken" "likes" "Clojure")
The process of extracting smaller constituents from a data structure is known as destructure.
Let’s assume that the data structures are properly bound to the symbols.
(def a-list (range 10)) ;; 0, 1, 2, ... 9
(first a-list) ;; 0
(rest a-list) ;; 1, 2, ... 9
(nth a-list 2) ;; 2
(last a-list) ;; 9
(def a-vector [:a :b :c :d])
;; just treat a vector as a list
(first a-vector) ;; :a
;; can do random-access very efficiently
(get a-vector 2) ;; :c - zero-indexed
(def a-map {:name "Ken"
:likes ["Programming" "Clojure"]
:office {:building "UA"
:room "4041"}})
;; Getting by key
(get a-map :name) ;; Ken
(get a-map :first-name) ;; nil
(get a-map :first-name :unknown) ;; :unknown
;; Get from inner maps
(get (get a-map :office) :room) ;; "4041"
(get (get a-map :likes) 0) ;; "Programming"
;; Get from Inner maps
(get-in a-map [:office :room]) ;; "4041"
(get-in a-map [:likes 0]) ;; "Programming"
See [1] for details.
Data modification is not supported by Clojure. So, instead of modifying existing data, we generate an incrementally altered copy.
Conjoin:
(conj [:a :b :c] :d) ;; [:a :b :c :d]
(conj '(:a :b :c) :d) ;; (:d :a :b :c)
(conj {:a 1, :b 2} [:c 3]) ;; {:a 1, :b 2, :c 3}
conj
adds an element to a collection in the most
efficient manner.
Associate:
(assoc {:a 1 :b 2} :c 3) ;; {:a 1 :b 2 :c 3}
Cons:
(cons :d [:a :b :c]) ;; (:d :a :b :c)
(cons :d '(:a :b :c)) ;; (:d :a :b :c)
cons
always:
Only vectors and hashmaps can be “updated”.
(assoc [1 -2 3] 1 2) ;; [1 2 3]
(assoc {:name "K"
:likes ["Programming" "Clojure"]} :name "Ken")
(assoc-in {:name "K"
:likes ["Programming" "Clojure"]}
[:likes 0] "Teach")
;; Deleting from a list
(drop 1 '(:a :b :c)) ;; (:b :c)
(pop '(:a :b :c)) ;; (:b :c)
;; Delete from vector
(drop 1 [:a :b :c]) ;; (:b :c)
(pop [:a :b :c]) ;; [:a :b]
;; Delete from hashmap
(dissoc {:name "Ken"
:office "UA4041"} :office) ;; {:name "Ken"}
;; Delete from set
(dissoc #{ :red :blue :green :white } :white) ;; #{:red :blue :green}
See [2] for more data transformation functions.