给定一个数据结构,我想重新构造它以按其中一个嵌套值进行分组。这些值是向量,每当我遇到多个值时,我就会卡住。
给出这样的地图矢量:
(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]}))