如何将地图列表转换为嵌套地图?

ue

从数据库中获取地图列表(LazySeq)的数据使我需要将其转换为地图地图。

我试图进行“关联”和“合并”,但是由于嵌套的原因并没有带来预期的结果。

这是我的数据的形式:

(def data (list {:structure 1 :cat "A" :item "item1" :val 0.1}
                {:structure 1 :cat "A" :item "item2" :val 0.2}
                {:structure 1 :cat "B" :item "item3" :val 0.4}
                {:structure 2 :cat "A" :item "item1" :val 0.3}
                {:structure 2 :cat "B" :item "item3" :val 0.5}))

我想以表格的形式得到它

=> {1 {"A" {"item1" 0.1}
            "item2" 0.2}}
      {"B" {"item3" 0.4}}
    2 {"A" {"item1" 0.3}}
      {"B" {"item3" 0.5}}}

我试过了

(->> data
     (map #(assoc {} (:structure %) {(:cat %) {(:item %) (:val %)}}))
     (apply merge-with into))

这给

{1 {"A" {"item2" 0.2}, "B" {"item3" 0.4}},
 2 {"A" {"item1" 0.3}, "B" {"item3" 0.5}}}

通过合并,我会丢失一些条目,但是我无法想到其他任何方式。有没有简单的方法?我什至正要尝试使用幽灵。

任何想法将不胜感激。

皮特23

如果我正在处理嵌套映射,那么通常首先要考虑的是update-in或assoc-in-它们采用一系列嵌套键。对于此类数据非常规则的问题,它很简单。

(assoc-in {} [1 "A" "item1"] 0.1)
;; =>
{1 {"A" {"item1" 0.1}}}

要将序列消耗成其他东西,减少是惯用的选择。减少功能就在我认为是匿名fn的复杂性级别的边缘,因此为了清楚起见,我将其删除。

(defn- add-val [acc line]
   (assoc-in acc [(:structure line) (:cat line) (:item line)] (:val line)))

(reduce add-val {} data)
;; =>
{1 {"A" {"item1" 0.1, "item2" 0.2}, "B" {"item3" 0.4}},
 2 {"A" {"item1" 0.3}, "B" {"item3" 0.5}}}

我认为这是您想要的效果。

行驶较少的道路:

由于您的序列来自数据库,因此我不必担心使用瞬态集合来加快聚合速度。另外,现在我考虑一下,无论如何,处理嵌套的瞬态图都是很痛苦的。

例如,如果您想使用相同的键来添加任何值,则update-in会很方便,但是问题的含义是结构/猫/项目元组是唯一的,因此您只需要分组即可。

juxt可用于生成密钥结构-即

((juxt :structure :cat :item) (first data))
[1 "A" "item1"]

但是我不清楚,有没有办法使用它来使add-val fn更具可读性。

Este artigo é coletado da Internet.

Se houver alguma infração, entre em [email protected] Delete.

editar em
0

deixe-me dizer algumas palavras

0comentários
loginDepois de participar da revisão

Artigos relacionados