我可以将地图列表"转置"到Clojure中的列表地图中吗?

jay*_*100 5 transpose list clojure map

您好:我想为地图中的所有值映射"平均值".说我有一张地图清单:

[{"age" 2 "height" 1 "weight" 10},
{"age" 4 "height" 4 "weight" 20},
{"age" 7 "height" 11 "weight" 40}]
Run Code Online (Sandbox Code Playgroud)

而我想要的输出是

{"age 5 "height" 5 ....}
Run Code Online (Sandbox Code Playgroud)

///下面是我大脑的谣言,也就是我想象这在Clojure工作的方式......不要太认真

转置清单:

  {"age" [2 4 7] "height" [1 4 11] } 
Run Code Online (Sandbox Code Playgroud)

然后我可以简单地做一些事情(再次,在这里编写一个名为freduce的函数)

  (freduce average (vals (map key-join list)))
Run Code Online (Sandbox Code Playgroud)

要得到

{"age" 5 "weight" 10 "height" 7}

Ale*_*art 6

创建矢量地图:

(reduce (fn [m [k v]]
          (assoc m k (conj (get m k []) v)))
        {}
        (apply concat list-of-maps))

创建平均值图:

(reduce (fn [m [k v]]
          (assoc m k (/ (reduce + v) (count v))))
        {}
        map-of-vectors)


man*_*nge 5

看看合并与

这是我的一些实际代码:

(let [maps [{"age" 2 "height" 1 "weight" 10},
            {"age" 4 "height" 4 "weight" 20},
            {"age" 7 "height" 11 "weight" 40}]]
  (->> (apply merge-with #(conj %1 %2)
             (zipmap (apply clojure.set/union (map keys maps))
                     (repeat [])) ; set the accumulator
             maps)
       (map (fn [[k v]] [k (/ (reduce + v) (count v))]))
       (into {})))
Run Code Online (Sandbox Code Playgroud)


ama*_*loy 4

这是一个相当详细的解决方案。希望有人能想出更好的办法:

(let [maps [{"age" 2 "height" 1 "weight" 10},
            {"age" 4 "height" 4 "weight" 20},
            {"age" 7 "height" 11 "weight" 40}]
      ks (keys (first maps))
      series-size (count maps)
      avgs (for [k ks]
             (/ (reduce +
                        (for [m maps]
                          (get m k)))
                series-size))]
  (zipmap ks avgs))
Run Code Online (Sandbox Code Playgroud)