それぞれに親を持つノードのリストがあり、これらからツリーを構築したいと考えています。
(def elems '[{:node A :parent nil} {:node B :parent A} {:node C :parent A} {:node D :parent C}])
(build-tree elems)
=> (A (B) (C (D)))
現在、私はこのコードを持っています:
(defn root-node [elems]
(:node (first (remove :parent elems))))
(defn children [elems root]
(map :node (filter #(= root (:parent %)) elems)))
(defn create-sub-tree [elems root-node]
(conj (map #(create-sub-tree elems %) (children elems root-node)) root-node))
(defn build-tree [elems]
(create-sub-tree elems (root-node elems)))
このソリューションでは、再帰が使用されていますが、ループ再帰構文では使用されていません。コードを最適化できず、StackOverflowError が発生する可能性があるため、これは悪いことです。
各ステップで再帰が1つある場合にのみ、再帰を使用できるようです。
ツリーの場合、ノードの子ごとに再帰があります。
この問題に遭遇しないように調整されたソリューションを探しています。
この問題に対する完全に異なる解決策がある場合は、ぜひご覧ください。
ジッパーについて少し読んだことがありますが、おそらくこれはツリーを構築するためのより良い方法です。