Clojure / Clojurescript:按多个值的地图分组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Clojure / Clojurescript:按多个值的地图分组相关的知识,希望对你有一定的参考价值。

给定一个数据结构,我想重新构造它以按其中一个嵌套值进行分组。这些值是向量,每当我遇到多个值时,我就会卡住。

给出这样的地图矢量:

(def tools 
 [{:name "A",
   :config
   {:accepts ["id"],
    :classes ["X"]}}
  {:name "B",
   :config
   {:accepts ["id"],
    :classes ["X", "Y"]
    }}])

我几乎可以得到我想要的东西 - 按“类”排序的值作为键,如果需要,重复值 - 通过运行group-by

(group-by #(get-in % [:config :classes]) tools)

但它需要:classes中的整个向量作为关键。

 {["X"] [{:name "A", 
          :config {:accepts ["id"], 
                   :classes ["X"]}}], 
  ["X" "Y"] [{:name "B", 
              :config {:accepts ["id"], 
                       :classes ["X" "Y"]}}]}

我真正想要的是每个类复制一次值,如下所示:

 {"X" [{:name "A"
        :config {:accepts ["id"]
                 :classes ["X"]}}
       {:name "B"
        :config {:accepts ["id"]
                 :classes ["X" "Y"]}}]
  "Y" [{:name "B"
        :config {:accepts ["id"]
                 :classes ["X" "Y"]}}]}

鉴于我在classes中有多个值,我不太清楚如何处理这个问题。

工作repl演示:https://repl.it/@YoYehudi/FamiliarDisguisedXiphiasgladius

答案

这是使用嵌套reduce的方法:

(defn aggregate-classes [m tool]
  (->> (get-in tool [:config :classes])
       (reduce (fn [acc elem]
                 (update acc elem conj tool))
               m)))

(reduce aggregate-classes {} tools)
=>
{"X" ({:name "B", :config {:accepts ["id"], :classes ["X" "Y"]}} {:name "A", :config {:accepts ["id"], :classes ["X"]}}),
 "Y" ({:name "B", :config {:accepts ["id"], :classes ["X" "Y"]}})}
另一答案
(apply merge-with into {}
       (for [tool tools
             class (get-in tool [:config :classes])]
         {class [tool]}))

以上是关于Clojure / Clojurescript:按多个值的地图分组的主要内容,如果未能解决你的问题,请参考以下文章

论前端框架组件状态抽象方案, 基于 ClojureScript 的 Respo 为例

惯用的 Clojure 函数别名

如何在 LeanCloud 上托管 Clojure web 应用

Roam Research 为何选择 Clojure 作开发语言

2018年度业余学习总结

测试“进入”是不是成功的函数