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

时间:2017-12-28 15:44:22

标签: 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

2 个答案:

答案 0 :(得分:3)

以下是使用嵌套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"]}})}

答案 1 :(得分:3)

(apply merge-with into {}
       (for [tool tools
             class (get-in tool [:config :classes])]
         {class [tool]}))