次のツリー(またはマップやベクトルを含むClojureの他のフォーム)があるとします。
'( (a b) (c d) )
フォーム全体の深さ優先走査に従って各サブフォームにインデックスを付け、フォームの子(存在する場合)のインデックスのベクトル(またはリスト)も提供するマップをClojureで生成したいと思います。
0 -> a []
1 -> b []
2 -> (a b) [0 1]
3 -> c []
4 -> d []
5 -> (c d) [3 4]
6 -> ( (a b) (c d) ) [2 5]
私はこれまでclojure.walkを使用して最初の部分(サブフォームのインデックス付け)を作成することしかできませんでしたが、子のインデックスを生成する方法についても困惑しています。私のコードは最後に追加され、次のように生成されます。
user=> (depthFirstIndexing '( (a b) (c d) ))
{6 ((a b) (c d)), 5 (c d), 4 d, 3 c, 2 (a b), 1 b, 0 a}
したがって、サブフォームのインデックスは深さ優先走査に従って正しく生成されますが、すべてのサブフォームの子のインデックスを取得する方法がわかりません。zippersモジュールを使用しようとしましたが、インデックスを収集するために深さ優先走査を実行する方法がわかりませんでした。
途中のコード
(use 'clojure.walk)
(defn depthFirstIndexing [aform]
(let [counter (atom -1)
idxToSubform (atom {})
]
(postwalk (fn [x]
(def idx (swap! counter inc))
(swap! idxToSubform assoc idx x)
x)
aform)
@idxToSubform))