Clojure将变换函数应用于地图的值

时间:2015-08-26 10:11:37

标签: dictionary clojure hashmap reducers

假设我有一张地图:

 {:top 2.8421709430404007E-14, :left 0, :down 240, :right 400N}

如何迭代它以将所有内容转换为整数?

 {:top 0, :left 0, :down 240, :right 400}

一个明显的解决方案是:

 {:top (:top m), :left (:left m), :down (:down m), :right (:right m)}

但感觉非常重复。

我觉得减少功能在这里可以做得很好,但我不确定如何。

2 个答案:

答案 0 :(得分:3)

对条目执行map可能是另一种方式:

(into {} (map (fn [[k v]] [k (int v)]) m))
;; {:top 0, :left 0, :down 240, :right 400}

答案 1 :(得分:2)

我必须使用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}

编辑: algo.generic.fmap看起来也可以。

编辑之二: 感谢@Andre提到map-valsweavejester/medley都存在prismatic/plumbing函数。

来自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))

来自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))))