2

Given the map:

(def myMap {"a" 1 "b" 2 "c" 3 "d" 4 "e" 5 "f" 6})

I wish to use let to bind each key to each value. What is the most concise way to do this?

user2179977
  • 656
  • 6
  • 14

2 Answers2

10

with myMap as declared, destructuring of string keys seems like the best bet:

(let [{:strs [a b c d e f]} myMap] 
    (println a b c d e f))
;=> 1 2 3 4 5 6
sw1nn
  • 7,278
  • 1
  • 26
  • 36
2

You can use desctructuring:

I would suggest first to convert all keys to keywords using custom function like this:

(defn keywordize [map]
  (into {} 
    (for [[k v] map]
      [(keyword k) v])))

And then use destructuring:

(let [{:keys [a b c d e f]} (keywordize myMap)]
  (println a b c d e f))
Mikita Belahlazau
  • 15,326
  • 2
  • 38
  • 43
  • Beat me to it, Nikita. – ChrisDevo Apr 08 '14 at 12:00
  • Thanks Nikita, conversion to keywords looks like a good step. However, with respect, I find the destructuring a little inelegant (not that I could do better :)). Suppose there were 100 keys in the map, I would need to write `[{:keys [a1 a2 a3 a4 a5 ... a98 a99 a100]} (keywordize myMap)]`. – user2179977 Apr 08 '14 at 12:07
  • 1
    You could create a vector using `(vec keys myMap)` of the keywords automatically and pass that to the :keys function. – ChrisDevo Apr 08 '14 at 12:11
  • That should be `(vec (keys myMap))`. – ChrisDevo Apr 08 '14 at 12:29
  • 1
    @ChrisDevo - :keys isn't a function in this case, so you can't just pass in ``(vec (keys myMap))``, you would need a macro to do what you propose. – sw1nn Apr 08 '14 at 12:45
  • 2
    @user2179977 A function that requires a hundred arguments, all playing different roles, is quite unlikely. Remember that you need only destructure the ones the function needs. If the hundred arguments were homogeneous, you'd probably supply them as a vector. – Thumbnail Apr 08 '14 at 17:38