我想转换一张地图的数值到另一个地图相同的密钥但有一个功能应用于价值观。我想有一个能这样做在题api,但是我已经无法找到它。

这里有一个例子,执行我在寻找什么

(defn map-function-on-map-vals [m f]
  (reduce (fn [altered-map [k v]] (assoc altered-map k (f v))) {} m))
(println (map-function-on-map-vals {:a "test" :b "testing"} #(.toUpperCase %)))
{:b TESTING, :a TEST}

没有任何人知道如果 map-function-on-map-vals 已经存在?我会认为它没有(很可能有一个更好的名字太)。

有帮助吗?

解决方案

我喜欢你reduce版本就好了。我认为这是地道。这里使用列表中理解反正是一个版本。

(defn foo [m f]
  (into {} (for [[k v] m] [k (f v)])))

其他提示

你可以使用 clojure.algo.generic.functor/fmap:

user=> (use '[clojure.algo.generic.functor :only (fmap)])
nil
user=> (fmap inc {:a 1 :b 3 :c 5})
{:a 2, :b 4, :c 6}

下面是改造的映射图的相当典型的方式。 zipmap 采取键列表和值的列表和“做正确的事”产生一个新的Clojure地图。你也可以把map周围的键来改变他们,或两者兼而有之。

(zipmap (keys data) (map #(do-stuff %) (vals data)))

或将其包装在你的功能:

(defn map-function-on-map-vals [m f]
    (zipmap (keys m) (map f (vals m))))
从Clojure的食谱两者

,则减少千伏:

(defn map-kv [m f]
  (reduce-kv #(assoc %1 %2 (f %3)) {} m))

下面是做到这一点相当惯用的方式:

(defn map-function-on-map-vals [m f]
        (apply merge
               (map (fn [[k v]] {k (f v)})
                    m)))

示例:

user> (map-function-on-map-vals {1 1, 2 2, 3 3} inc))
{3 4, 2 3, 1 2}

map-map, map-map-keys, , map-map-values

我知道没有现有的功能和为此,但这里的一个执行这一功能作 map-map-values 你是免费复制。它有两个密切相关的职能, map-mapmap-map-keys, ,这也是缺失的标准图书馆:

(defn map-map
    "Returns a new map with each key-value pair in `m` transformed by `f`. `f` takes the arguments `[key value]` and should return a value castable to a map entry, such as `{transformed-key transformed-value}`."
    [f m]
    (into (empty m) (map #(apply f %) m)) )

(defn map-map-keys [f m]
    (map-map (fn [key value] {(f key) value}) m) )

(defn map-map-values [f m]
    (map-map (fn [key value] {key (f value)}) m) )

使用

你可以打电话 map-map-values 是这样的:

(map-map-values str {:a 1 :b 2})
;;           => {:a "1", :b "2"}

和其他两个功能是这样的:

(map-map-keys str {:a 1 :b 2})
;;         => {":a" 1, ":b" 2}
(map-map (fn [k v] {v k}) {:a 1 :b 2})
;;    => {1 :a, 2 :b}

代替实现

如果你只想要的 map-map-keysmap-map-values, ,而不多大 map-map 功能,可以使用这些实现,而不要依赖 map-map:

(defn map-map-keys [f m]
    (into (empty m)
        (for [[key value] m]
            {(f key) value} )))

(defn map-map-values [f m]
    (into (empty m)
        (for [[key value] m]
            {key (f value)} )))

此外,这里有一个备选执行情况 map-map 这是基于 clojure.walk/walk 而不是的 into, 如果你喜欢这措辞:

(defn map-map [f m]
    (clojure.walk/walk #(apply f %) identity m) )

平行的版本 pmap-map, 等等。

也有平行的版本的这些职能如果你需要他们。他们只是使用 pmap 而不是的 map.

(defn pmap-map [f m]
    (into (empty m) (pmap #(apply f %) m)) )
(defn pmap-map-keys [f m]
    (pmap-map (fn [key value] {(f key) value}) m) )
(defn pmap-map-values [f m]
    (pmap-map (fn [key value] {key (f value)}) m) )

我是一个Clojure的的n00b,所以有可能是更优雅的解决方案。这里的矿:

(def example {:a 1 :b 2 :c 3 :d 4})
(def func #(* % %))

(prn example)

(defn remap [m f]
  (apply hash-map (mapcat #(list % (f (% m))) (keys m))))

(prn (remap example func))

在不久FUNC使得从每个键及其f'ed值有点2-列表。会员名:mapcat运行在地图上的按键顺序此功能并连接整个工程进入一个大名单。 “应用哈希地图”创建与序列的新地图。的(%m)可以看起来有点怪异,这是惯用的Clojure用于施加一键的映射来查找相关联的值。

最强烈推荐阅读:该的Clojure速查表

我喜欢你reduce版本。具有非常轻微的变化,它也能保持记录结构的类型:

(defn map-function-on-map-vals [m f]
  (reduce (fn [altered-map [k v]] (assoc altered-map k (f v))) m m))

{}通过m取代。与该改变,记录保留记录:

(defrecord Person [firstname lastname])

(def p (map->Person {}))
(class p) '=> Person

(class (map-function-on-map-vals p
  (fn [v] (str v)))) '=> Person

通过与{}开始,记录失去了它的 recordiness 的,其中之一可能要保留,如果你想要的记录功能(例如紧凑内存表示)。

(defn map-vals
  "Map f over every value of m.
   Returns a map with the same keys as m, where each of its values is now the result of applying f to them one by one.
   f is a function of one arg, which will be called which each value of m, and should return the new value.
   Faster then map-vals-transient on small maps (8 elements and under)"
  [f m]
  (reduce-kv (fn [m k v]
               (assoc m k (f v)))
             {} m))

(defn map-vals-transient
  "Map f over every value of m.
   Returns a map with the same keys as m, where each of its values is now the result of applying f to them one by one.
   f is a function of one arg, which will be called which each value of m, and should return the new value.
   Faster then map-vals on big maps (9 elements or more)"
  [f m]
  (persistent! (reduce-kv (fn [m k v]
                            (assoc! m k (f v)))
                          (transient {}) m)))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top