Reputation: 18005
Let's say I have a map :
{:top 2.8421709430404007E-14, :left 0, :down 240, :right 400N}
How can I iterate over it to convert everything into integers ?
{:top 0, :left 0, :down 240, :right 400}
An obvious solution would be :
{:top (:top m), :left (:left m), :down (:down m), :right (:right m)}
but it feels very repetitive.
I feel a reducing function could do nicely here, but I'm not sure how.
Upvotes: 1
Views: 631
Reputation: 10865
Doing a map
over the entries could be another way:
(into {} (map (fn [[k v]] [k (int v)]) m))
;; {:top 0, :left 0, :down 240, :right 400}
Upvotes: 3
Reputation: 18005
I had to use reduce-kv
:
(reduce-kv #(assoc %1 %2 (int %3)) {} {:top 2.8421709430404007E-14, :left 0, :down 240, :right 400N})
;;=>{:down 240, :left 0, :right 400, :top 0}
Edit : algo.generic.fmap
looks like it would work as well.
Edit bis :
Thanks to @Andre for mentioning that a map-vals
function exists in both weavejester/medley
or prismatic/plumbing
.
From medley
:
(defn map-vals
"Maps a function over the values of an associative collection."
[f coll]
(reduce-map (fn [xf] (fn [m k v] (xf m k (f v)))) coll))
From plumbing
:
(defn map-vals
"Build map k -> (f v) for [k v] in map, preserving the initial type"
[f m]
(cond
(sorted? m)
(reduce-kv (fn [out-m k v] (assoc out-m k (f v))) (sorted-map) m)
(map? m)
(persistent! (reduce-kv (fn [out-m k v] (assoc! out-m k (f v))) (transient {}) m))
:else
(for-map [[k v] m] k (f v))))
Upvotes: 2