从数据库中获取地图列表(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}}}
通过合并,我会丢失一些条目,但是我无法想到其他任何方式。有没有简单的方法?我什至正要尝试使用幽灵。
任何想法将不胜感激。
如果我正在处理嵌套映射,那么通常首先要考虑的是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.
deixe-me dizer algumas palavras