在Clojure中合并地图

时间:2014-04-13 16:06:48

标签: data-structures clojure

我正在寻找合并4个独立地图列表的方法。我正在抓一个网站,它给我一个下面data*形式的attrs列表......

(def data1 '("1" "1" "1" "1"))
(def data2 '("2" "2" "2" "2"))
(def data3 '("3" "3" "3" "3"))
(def data4 '("4" "4" "4" "4"))

......而他们我按照钥匙组织他们:

(map #(assoc {} :a %) data1)
(map #(assoc {} :b %) data2)
(map #(assoc {} :c %) data3)
(map #(assoc {} :d %) data4)

上面的代码产生以下数据结构:

({:a "1"} {:a "1"} {:a "1"} {:a "1"})
({:b "2"} {:b "2"} {:b "2"} {:b "2"})
({:c "3"} {:c "3"} {:c "3"} {:c "3"})
({:d "4"} {:d "4"} {:d "4"} {:d "4"})

我想垂直组合这些列表,所以我有以下内容:

(def want [{:a "1", :b "2", :c "3", :d "4"}
           {:a "1", :b "2", :c "3", :d "4"}
           {:a "1", :b "2", :c "3", :d "4"}
           {:a "1", :b "2", :c "3", :d "4"}])

这将允许我迭代地图列表并从每个地图中选择一个特定值,将它们吐出到网页上。但我不确定如何获得数据结构want。任何帮助表示赞赏...

2 个答案:

答案 0 :(得分:4)

Map从提供的集合中获取第一,第二等的每个组合,并对每个集合执行一个函数。所以它对于转置集合非常有用。此处显示Vector是说明转置的最简单函数:

(map vector
  [{:a "1"} {:a "1"} {:a "1"} {:a "1"}]
  [{:b "2"} {:b "2"} {:b "2"} {:b "2"}]
  [{:c "3"} {:c "3"} {:c "3"} {:c "3"}]
  [{:d "4"} {:d "4"} {:d "4"} {:d "4"}]))

=>([{:a "1"} {:b "2"} {:c "3"} {:d "4"}]
   [{:a "1"} {:b "2"} {:c "3"} {:d "4"}]
   [{:a "1"} {:b "2"} {:c "3"} {:d "4"}]
   [{:a "1"} {:b "2"} {:c "3"} {:d "4"}])

Merge结合了哈希映射:

(merge {:a "1"} {:b "2"} {:c "3"} {:d "4"})
=> {:d "4", :c "3", :b "2", :a "1"}

将两者合并为你想要的效果:

(map merge
     [{:a "1"} {:a "1"} {:a "1"} {:a "1"}]
     [{:b "2"} {:b "2"} {:b "2"} {:b "2"}]
     [{:c "3"} {:c "3"} {:c "3"} {:c "3"}]
     [{:d "4"} {:d "4"} {:d "4"} {:d "4"}]))

=>({:d "4", :c "3", :b "2", :a "1"}
   {:d "4", :c "3", :b "2", :a "1"}
   {:d "4", :c "3", :b "2", :a "1"}
   {:d "4", :c "3", :b "2", :a "1"})

答案 1 :(得分:4)

我不清楚你为什么要做中间步骤

(map #(assoc {} :a %) ...)

如果您的数据是

(def data [["1" "1" "1" "1"] 
           ["2" "2" "2" "2"] 
           ["3" "3" "3" "3"] 
           ["4" "4" "4" "4"]])

你的钥匙是

(def my-keys [:a :b :c :d])

然后你可以使用zipmap

(mapv zipmap (repeat my-keys) (apply map list data))


;=> [{:d "4", :c "3", :b "2", :a "1"}
;    {:d "4", :c "3", :b "2", :a "1"}
;    {:d "4", :c "3", :b "2", :a "1"}
;    {:d "4", :c "3", :b "2", :a "1"}]

注意(apply map list data)用于将数据转换为与键相关的正确方向。