Read Clojure Map Values 2/2

Here is another chapter of the series.

For those who missed the previous chapter:

We are going to continue to explore how to read clojure map.

This time we are going to talk about keys, vals and select-keys.

keys and vals

keys and vals are extremely similar.

keys return a sequence of all the keys of a map.

user> (keys {:a 1 :b 2 :c 3 :d 4})
(:c :b :d :a)

vals return a sequence of all the values of a map.

user> (vals {:a 1 :b 2 :c 3 :d 4})
(3 2 4 1)

Using keys and vals you need to remember that there is no order inside a simple hash-map so you cannot make any assumption about the final sequence.

However if you use sorted-map or also array-map you can assume that the order of the keys and the order of the values will be maintained.

user> (keys (sorted-map :a 1 :b 2 :c 3 :d 4))
(:a :b :c :d)
user> (vals (sorted-map :a 1 :b 2 :c 3 :d 4))
(1 2 3 4)
user> (keys (array-map :a 1 :b 2 :c 3 :d 4))
(:a :b :c :d)
user> (vals (array-map :a 1 :b 2 :c 3 :d 4))
(1 2 3 4)

Something pretty obvious but useful to remember the use of keys and vals is the following snippet.

user> (let [m {:a 1 :b 2}]
	    (= (zipmap (keys m) (vals m)) m))
true

select-keys

This function is useful to shrink map.

Given a map and a sequence of keys return the map shrinked to only the keys in the sequence.

user> (select-keys {:a 1 :b 2 :c 3} [:a :c])
{:c 3, :a 1}
user> (select-keys {:a 1 :b 2 :c 3} [:a :c :d])
{:c 3, :a 1}

As you can see if a key is not present in the original map the returning map won’t contains such key.

What we need to note here is that select-keys takes only two arguments, the starting map and a vector of keys.

You may try to pass the keys to select as a simple arguments but that will result in a pretty cryptic error.

user> (select-keys {:a 1 :b 2 :c 3} :a :b) ;; ok understandable
ArityException Wrong number of args (3) passed to: core/select-keys  clojure.lang.AFn.throwArity (AFn.java:429)
user> (select-keys {:a 1 :b 2 :c 3} :a) ;; pretty cryptic
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword  clojure.lang.RT.seqFrom (RT.java:505)

end

This was the last chapter about reading clojure map.

Next time we are going to explore deeply how to modify a map adding and removing entries.

As always stay tunned, and for any question don’t esitate to write me.

Next Chapter: Map transformation in clojure 1/2 assoc, dissoc, merge

I am available for freelance work, I am specialized in IoT and distributed fault tolerant systems, if you are interested in working with me you can get in touch here: simone [at] mweb [dot] biz