Clojure, hash-map, keys, keyword
tldr; Simple strings can be used as key
to a hash-map
. Either use get
to lookup for them. Or convert them into keyword
using keyword
method.
hash-map
are an essential Data Structures of Clojure. They support an interesting feature of keyword
that can really enhance lookup experience in Clojure hash-map
.
;; Placeholder, improve it
user=> (def languages {:python "Everything is an Object."
:clojure "Everything is a Function."
:javascript "Whatever you would like it to be."})
;; To lookup in map
user=> (:python languages)
"Everything is an Object."
user=> (get languages :ruby)
nil
Syntax is easy to understand and easy to follow. So far so good. I started using it here and there. At a point I came to a situation where I had to do a lookup in a map, using a variable:
user=> (def brands {:nike "runnin shoes"
#_=> :spalding "basketball"
#_=> :yonex "badminton"
#_=> :wilson "tennis racquet"
#_=> :kookaburra "cricket ball"})
(def brand-name "yonex")
Because we have used keyword
in map brands
, we can't user value stored in variable brand-name
directly to do a lookup in the map. I tried silly things like :str(brand-name)
(results in Execution error
) or :brand-name
(returns nil
). I got confused on how to do this. Almost all examples in docs were using keyword
. I tried a few things and understood that we can indeed use string
as key and to fetch the value use get
function:
user=> (def brands {"nike" "runnin shoes"
#_=> "spalding" "basketball"
#_=> "yonex" "badminton"
#_=> "wilson" "tennis racquet"
#_=> "kookaburra" "cricket ball"})
#'user/brands
user=> (get brands brand-name)
"badminton"
While using keyword
has simpler syntax, at times when I am using external APIs it is easier to work with string
or lookup for a key in hash-map
using variable. In python
I do it all the time. Though I am not sure if using string
as key
is the recommended way.
Update
punch and I were discussing this post and he mentioned that in lisp
we can use keyword
as method to convert string into a keyword
. After a quick search, TIL, indeed we can keyword
a variable. The method converts string into a equivalent keyword
:
user=> (def brands {"nike" "runnin shoes"
#_=> "spalding" "basketball"
#_=> "yonex" "badminton"
#_=> "wilson" "tennis racquet"
#_=> "kookaburra" "cricket ball"})
#'user/brands
user=> (keyword brand-name)
:yonex
user=> ((keyword brand-name) brands)
"badminton"