将地图向量转换为树
Convert vector of maps to a tree
我需要像这样转换地图矢量:
[{:id 1 :parent nil :name "a"}
{:id 2 :parent 1 :name "b"}
{:id 3 :parent 2 :name "c"}
{:id 4 :parent 2 :name "d"}
{:id 5 :parent 4 :name "e"}]
对此:
[{:id 1
:parent nil
:name "a"
:nodes [{:id 2
:parent 1
:name "b"
:nodes [{:id 3
:parent 2
:name "c"}
{:id 4
:parent 2
:name "d"
:nodes [{:id 5 :parent 4 :name "e"}]}]}]}]
更新:
根据目前的要求,我有这个:
(defn enum [s]
(map vector (range) s))
(defn build-tree [tree current-path current-parent gr]
(if-let [nodes (gr current-parent)]
(let [current-path (conj current-path :nodes)
new-tree (assoc-in tree current-path nodes)]
(first
(for [[i node] (enum (get-in new-tree current-path))]
(build-tree new-tree (conj current-path i) (:id node) gr))))
tree))
(defn list->tree [ls]
(let [gr (group-by :parent ls)
root (first (gr nil))]
(build-tree root [] (:id root) gr)))
但是我真的怀疑这是惯用的+它无论如何都不起作用(只创建第一个节点,其余的被忽略)。我也怀疑创造一棵树是如此困难。我真的觉得我错过了什么。
您可以使用邻接表或递归方法。
这两种方法都作为答案进行了更详细的讨论 。
我需要像这样转换地图矢量:
[{:id 1 :parent nil :name "a"}
{:id 2 :parent 1 :name "b"}
{:id 3 :parent 2 :name "c"}
{:id 4 :parent 2 :name "d"}
{:id 5 :parent 4 :name "e"}]
对此:
[{:id 1
:parent nil
:name "a"
:nodes [{:id 2
:parent 1
:name "b"
:nodes [{:id 3
:parent 2
:name "c"}
{:id 4
:parent 2
:name "d"
:nodes [{:id 5 :parent 4 :name "e"}]}]}]}]
更新:
根据目前的要求,我有这个:
(defn enum [s]
(map vector (range) s))
(defn build-tree [tree current-path current-parent gr]
(if-let [nodes (gr current-parent)]
(let [current-path (conj current-path :nodes)
new-tree (assoc-in tree current-path nodes)]
(first
(for [[i node] (enum (get-in new-tree current-path))]
(build-tree new-tree (conj current-path i) (:id node) gr))))
tree))
(defn list->tree [ls]
(let [gr (group-by :parent ls)
root (first (gr nil))]
(build-tree root [] (:id root) gr)))
但是我真的怀疑这是惯用的+它无论如何都不起作用(只创建第一个节点,其余的被忽略)。我也怀疑创造一棵树是如此困难。我真的觉得我错过了什么。
您可以使用邻接表或递归方法。
这两种方法都作为答案进行了更详细的讨论