Convert an array of tuples into a hash-map in Clojure
14,290
Solution 1
user=> (into {} [[:a 1] [:b 2]])
{:a 1, :b 2}
Solution 2
A map is a sequence of MapEntry elements. Each MapEntry is a vector of a key and value. The tuples in the question are already in the form of a MapEntry, which makes things convenient. (That's also why the into
solution is a good one.)
user=> (reduce conj {} [[:a 1] [:b 2]])
{:b 2, :a 1}
Solution 3
Assuming that "tupel" means "two-elememt array":
(reduce
(fn [m tupel]
(assoc m
(aget tupel 0)
(aget tupel 1)))
{}
array-of-tupels)
Solution 4
user=> (def a [[:a 4] [:b 6]])
user=> (apply hash-map (flatten a))
{:a 4, :b 6}
Author by
Mantas Vidutis
always on the move. operating a consultancy in SF: turbines.io
Updated on June 05, 2022Comments
-
Mantas Vidutis about 2 years
I have an array of tuples, where each tuple is a 2 tuple with a key and a value. What would be the cleanest way to convert this array of tuples into a hash-map?
-
Isaac over 13 yearsNice. If your (to the OP) "array" is in fact a seq, instead of
(aget t n)
you can use(t n)
, which is a bit prettier. -
Michał Marczyk over 13 yearsNote that this also works for arrays of two-element arrays -- you'd just have to add a
(map vec ...)
around the array argument:(into {} (map vec an-array-of-two-element-arrays))
. -
Isaac over 13 yearsAnd again, one of those "duh" moments you so often have while using Clojure. Nice answer.
-
kotarak over 13 years
(t n)
does not work with sequences. It does with vectors. But then you can simply use(into {} array-of-vectors)
instead of thereduce
. -
kotarak over 13 yearsBut a relatively expensive one.
-
miner49r about 13 years
flatten
is overkill for this problem. You can take advantage of the tuples being in the form of a MapEntry (vector of key and value). -
Yu Shen about 9 yearsThanks for good explanation! So only vector of 2 elements is MapEntry, thus (into {} [[:a 1] {:b 2}]) will work, but (into {} ['( :a 1 ) {:b 2}]) will not work.It gets the error of "java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry". I wonder why can't Clojure treat all 2 elements sequence the same way in this context. It will make it more consistent. What's the reason it does not?
-
Radon Rosborough almost 8 yearsNever, ever use
flatten
for a situation like this: it will happily flatten all of your keys and values too, if they happen to be data structures! -
Dennis Hackethal about 4 years@MichałMarczyk I don't get it... if you already have an array of arrays, why map
vec
over them? I thinkvec
just leaves arrays as is... -
Greyshack over 3 yearsWhy does it have to be vector, why doesnt a list of two element lists work?