将地图中的函数基于其键应用于地图中的每个值

时间:2014-03-12 17:57:32

标签: clojure

假设我有一张地图:

{:name "foo"
 :age "bar"}

另一个

{:name (fn [val] (println val))
 :age (fn [val] (= val "bar"))}

我希望将第二张地图上:name键入的功能应用到第一张地图上,该地图也由:name键入,而:age键入的功能键入:age键入的第一张地图{1}}。怎么做clojure方式?

4 个答案:

答案 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))))