假设我有一张地图:
{:name "foo"
:age "bar"}
另一个
{:name (fn [val] (println val))
:age (fn [val] (= val "bar"))}
我希望将第二张地图上:name
键入的功能应用到第一张地图上,该地图也由:name
键入,而:age
键入的功能键入:age
键入的第一张地图{1}}。怎么做clojure方式?
答案 0 :(得分:7)
您可以使用merge-with
(def m1 {:name "foo"
:age "bar"})
(def m2 {:name (fn [val] (println val))
:age (fn [val] (= val "bar"))})
user=> (merge-with #(%1 %2) m2 m1)
foo
{:name nil, :age true}
答案 1 :(得分:1)
map
在一张地图上,并从另一张地图获得相应的功能。
(def m1 {:name "foo"
:age "bar"})
(def m2 {:name (fn [val] (println val))
:age (fn [val] (= val "bar"))})
(map (fn [[k v]]
((get m2 k) v))
m1)
地图上的每次迭代都会将一个向量传递给函数中的函数:
[:name "foo"]
[:age "bar"]
因此,将函数参数解构为[[k v]]
会分别为每个键/值提供。
答案 2 :(得分:1)
(def data { :name "don knotts"
:dob "1/1/1940"
:cob "Valdosta" })
(def fxns {:name identity :dob identity :cob clojure.string/reverse})
(defn bmap [data fxn]
(apply merge (for [[k1 d] data [k2 f] fxn :when (= k1 k2)]
{k1 (f d)})))
;=user>{:cob "atsodlaV", :dob "1/1/1940", :name "don knotts"}
答案 3 :(得分:0)
我喜欢这个,如果你需要更多弹性:
(defn fmm [m fm]
(let [f (fn [k] ((get fm k identity) (k m)))
ks (keys m)]
(zipmap ks (map f ks))))