如何获取地图,并将它们的键组合成地图向量?

问题描述 投票:0回答:3

我有这样的数据:

[{:a [{0 0}
     {2 2}
     {9 9}]}
 {:b [{2 2}
     {5 6}
     {7 7}]}
 {:c [{0 1}
     {5 5}
     {5 3}]}]

我想把它变成这样:

[{:a {0 0}
  :b {2 2}
  :c {0 1}}
 {:a {2 2}
  :b {5 6}
  :c {5 5}}
 {:a {9 9}
  :b {7 7}
  :c {5 3}}]

基本上,获取 (get :a m)、(get :b m)、(get :c m) 的第一个元素并制作一个新地图,然后获取 (get :a m) 、(get :b m) 的第二个元素, (得到:c m)并将其放入第二张地图等。这有点像获取矢量地图并将其转换为地图矢量。

限制,只能使用clojure.core.

我尝试过的-我最有前途的想法是采用

(flatten (mapv keys data))
(mapv vals abc)
并以某种方式组合数据。

clojure etl
3个回答
0
投票

一种方法是将每个内部对收集到包含索引和键的记录中,然后将它们重新整形为您想要的输出结构:

(defn transform [ms]
  (let [rs (for [m ms
                 [k ps] m
                 r (map-indexed (fn [idx p] {:k k :p p :index idx}) ps)]
             r)
        gs (->> rs (group-by :index) (sort-by first) (map second))]
    (mapv (fn [rs] (into {} (map (juxt :k :p) rs))) gs)))

0
投票

您可以使用对惰性序列进行操作的函数来完成此操作,例如

map
等等。
->>
是一个线程宏,通常用于组合对集合和惰性序列的操作:

(defn reshape-data [input]
  (let [fe (map first input)
        ks (map first fe)]
    (->> fe
         (map second)
         (iterate (partial map rest))
         (take-while (comp seq first))
         (map #(zipmap ks (map first %))))))

0
投票

对于值,这看起来像是转置。然后你想压缩 结果与所有密钥一起返回。

(defn transform
  [ms]
  (let [firsts (map first ms)
        keys (map key firsts)
        vals (map val firsts)
        transposed (apply map vector vals)]
    (mapv (partial zipmap keys) transposed)))

命名由你决定。

对于高尔夫,您还可以通过转置获得keys和vals:

(defn transform
  [ms]
  (let [[keys vals] (->> ms
                         (map first)
                         (apply map vector))]
    (mapv (partial zipmap keys)
          (apply map vector vals))))
© www.soinside.com 2019 - 2024. All rights reserved.