Tho*_*mas 129 dictionary clojure map-function
我想将一个值映射转换为另一个具有相同键但具有应用于值的函数的映射.我认为在clojure 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}
Run Code Online (Sandbox Code Playgroud)
有人知道是否map-function-on-map-vals
已经存在?我认为它确实(可能还有一个更好的名字).
Bri*_*per 143
我很喜欢你的reduce
版本.我认为这是惯用的.这是一个使用列表理解的版本.
(defn foo [m f]
(into {} (for [[k v] m] [k (f v)])))
Run Code Online (Sandbox Code Playgroud)
Art*_*ein 93
你可以使用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}
Run Code Online (Sandbox Code Playgroud)
Art*_*ldt 33
这是一种转换地图的典型方法.
zipmap
获取一个键列表和一个值列表,并"做正确的事"产生一个新的Clojure映射.您也可以放置map
密钥来更改它们,或两者兼而有之.
(zipmap (keys data) (map #(do-stuff %) (vals data)))
Run Code Online (Sandbox Code Playgroud)
或者将它包装在你的函数中:
(defn map-function-on-map-vals [m f]
(zipmap (keys m) (map f (vals m))))
Run Code Online (Sandbox Code Playgroud)
Ror*_*ane 23
Clojure 1.11clojure.core
在标准库中添加了一个函数。Clojure 1.11于 2022 年 3 月 22 日发布。
update-vals
(update-vals m f)
将函数应用于映射中的每个值。它返回一张新地图{k (f v) ...}
。
(update-vals {:a 1 :b 2} str)
;; => {:a "1", :b "2"}
Run Code Online (Sandbox Code Playgroud)
update-keys
(update-keys m f)
将函数应用于映射中的每个键。它返回一张新地图{(f k) v ...}
。产生的所有键(f k)
必须是唯一的。
Clojure 1.11 中也添加了此功能。
(update-keys {:a 1 :b 2} str)
;; => {":a" 1, ":b" 2}
Run Code Online (Sandbox Code Playgroud)
rob*_*oli 19
从Clojure Cookbook中获取,有reduce-kv:
(defn map-kv [m f]
(reduce-kv #(assoc %1 %2 (f %3)) {} m))
Run Code Online (Sandbox Code Playgroud)
这是一个相当惯用的方法:
(defn map-function-on-map-vals [m f]
(apply merge
(map (fn [[k v]] {k (f v)})
m)))
Run Code Online (Sandbox Code Playgroud)
例:
user> (map-function-on-map-vals {1 1, 2 2, 3 3} inc))
{3 4, 2 3, 1 2}
Run Code Online (Sandbox Code Playgroud)
map-map
, map-map-keys
, 和map-map-values
我知道 Clojure 中没有现有的函数用于此,但这里是该函数的实现,因为map-map-values
您可以自由复制。它带有两个密切相关的函数map-map
和map-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) )
Run Code Online (Sandbox Code Playgroud)
你可以这样调用map-map-values
:
(map-map-values str {:a 1 :b 2})
;; => {:a "1", :b "2"}
Run Code Online (Sandbox Code Playgroud)
其他两个函数是这样的:
(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}
Run Code Online (Sandbox Code Playgroud)
如果你只想要map-map-keys
or map-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)} )))
Run Code Online (Sandbox Code Playgroud)
此外,如果您更喜欢这种措辞,这里有一个map-map
基于clojure.walk/walk
而不是的替代实现into
:
(defn map-map [f m]
(clojure.walk/walk #(apply f %) identity m) )
Run Code Online (Sandbox Code Playgroud)
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) )
Run Code Online (Sandbox Code Playgroud)