私はいくつかのClojureコードに取り組んでおり、その中には次のようなエンティティのツリーがあります:
foo1
+-- bar1
| +-- baz1
| +-- baz2
+-- bar2
+-- baz3
foo2
+-- bar3
+-- baz4
私のばかげた ASCII アートが意味をなさない場合に備えて、それぞれが 0 個以上の bar を持つことができる foos のリストを持っています。それぞれが 0 個以上のbazesを持つことができます。
私がやろうとしているのは、キーがbaz ID で、値がバーID であるハッシュ マップを生成することです。つまり、上の図は次のようになります。
{"baz1" "bar1", "baz2" "bar1", "baz3" "bar2", "baz4" "bar3"}
私のデータ構造は次のようになります。
(def foos [
{:id "foo1" :bars [
{:id "bar1" :bazes [
{:id "baz1"}
{:id "baz2"}
]}
{:id "bar2" :bazes [
{:id "baz3"}
]}
]}
{:id "foo2" :bars [
{:id "bar3" :bazes [
{:id "baz4"}
]}
]}
])
そして、ここに私が持っている baz-to-bar マップを構築するコードがあります:
(defn- baz-to-bar [foos]
(let [b2b-list (flatten (for [f foos] (flatten (for [bar (:bars c)] (flatten (for [baz (:bazes bar)] [(:id baz) (:id bar)]))))))
b2b-map (if (not (empty? b2b-list)) (apply hash-map b2b-list))]
(if b2b-map [:b2b (for [baz (keys b2b-map)] (entry-tag baz (b2b-map baz)))])))
それは機能しますが、かなり鈍いです。
Clojureでこれを行うための、よりエレガントで、できれば慣用的な方法を提案できる人はいますか?