从多个地图和一个键列表到键列表和地图中的相应值

时间:2012-06-22 07:07:36

标签: collections clojure

输入:

List of keys: [ :name :address :work]
Map 1: { :name "A" :address "A Street" }
Map 2: { :work "Work Ave" }

输出:

([:name "A" nil] [:address "A Street" nil] [:work nil "Work Ave"])

这就是我现在所拥有的:

(defn maps-iterate [v & ms]
    (map (fn [k] (into [] [k #(map (k %) ms)])) v))

(println (maps-iterate [ :name :address :work ] { :name "A" :address "A Street"} { :work "Work Ave" }))

这给了我:

([:name #<user$maps_iterate$fn__2$fn__3 user$maps_iterate$fn__2$fn__3@4b14b82b>] 
 [:address #<user$maps_iterate$fn__2$fn__3 user$maps_iterate$fn__2$fn__3@3d47358f>] 
 [:work #<user$maps_iterate$fn__2$fn__3 user$maps_iterate$fn__2$fn__3@e0d5eb7>])

4 个答案:

答案 0 :(得分:2)

尝试

(defn maps-iterate [v & ms]
    (map (fn [k] (into [] [k (map #(k %) ms)])) v))

甚至更好:

(defn maps-iterate [v & ms]
    (map (fn [k] (cons k (map k ms))) v))

注意:如果所有键都是关键字,那么您可以将它们用作函数:(map k ms)而不是(map #(k %) ms)。如果不是,则不能将它们用作函数。你需要写(map #(% k) ms)

答案 1 :(得分:1)

这个怎么样?

(for [k ks]
  [k (map k [m1 m2])])
;;=> ([:name ("A" nil)] [:address ("A Street" nil)] [:work (nil "Work Ave")])

或者,如果你真的想在结果中使用平面向量:

(for [k ks]
  (apply vector k 
         (map k [m1 m2])))
;;=> ([:name "A" nil] [:address "A Street" nil] [:work nil "Work Ave"])

答案 2 :(得分:1)

user=> (def a { :name "A" :address "A Street" })
#'user/a
user=> (def b { :work "Work Ave" })
#'user/b
user=> (def c [ :name :address :work])
#'user/c
user=> (map #(vector %1 (%1 a) (%1 b)) c)
([:name "A" nil] [:address "A Street" nil] [:work nil "Work Ave"])

答案 3 :(得分:-1)

以下REPL示例生成输出,但未指示nil值:

user> (def map1 { :name "A" :address "A Street" })
#'user/map1
user> (def map2 { :work "Work Ave" })
#'user/map2
user> (seq (merge map1 map2))
([:work "Work Ave"] [:name "A"] [:address "A Street"])