Clojure / Clojurescript:按多个值的映射分组
Clojure / Clojurescript: group-by a map on multiple values
给定一个数据结构,我想重新构造它以按其中一个嵌套值分组。这些值是向量,每当遇到多个值时,我就会卡住。
给定一个这样的地图矢量:
(def tools
[{:name "A",
:config
{:accepts ["id"],
:classes ["X"]}}
{:name "B",
:config
{:accepts ["id"],
:classes ["X", "Y"]
}}])
我可以 几乎 得到我想要的 - 按 "classes" 作为键排序的值,如果需要重复值 - 按 运行 group-by
:
(group-by #(get-in % [:config :classes]) tools)
但是它是以:classes
中的整个向量作为key。
{["X"] [{:name "A",
:config {:accepts ["id"],
:classes ["X"]}}],
["X" "Y"] [{:name "B",
:config {:accepts ["id"],
:classes ["X" "Y"]}}]}
我真正想要的是每个 class 复制一次值,看起来像这样:
{"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]}))
给定一个数据结构,我想重新构造它以按其中一个嵌套值分组。这些值是向量,每当遇到多个值时,我就会卡住。
给定一个这样的地图矢量:
(def tools
[{:name "A",
:config
{:accepts ["id"],
:classes ["X"]}}
{:name "B",
:config
{:accepts ["id"],
:classes ["X", "Y"]
}}])
我可以 几乎 得到我想要的 - 按 "classes" 作为键排序的值,如果需要重复值 - 按 运行 group-by
:
(group-by #(get-in % [:config :classes]) tools)
但是它是以:classes
中的整个向量作为key。
{["X"] [{:name "A",
:config {:accepts ["id"],
:classes ["X"]}}],
["X" "Y"] [{:name "B",
:config {:accepts ["id"],
:classes ["X" "Y"]}}]}
我真正想要的是每个 class 复制一次值,看起来像这样:
{"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]}))