我正在研究一些Clojure代码,其中有一个像这样的实体树:
foo1
+-- bar1
| +-- baz1
| +-- baz2
+-- bar2
+-- baz3
foo2
+-- bar3
+-- baz4
万一我那荒唐的ASCII艺术没有意义,我有一个foos列表,每个foos可以具有零个或多个bar,每个bars可以具有零个或多个baze。
我想做的是生成一个哈希图,其中的键是baz 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"}
]}
]}
])
这是我拥有的构建巴兹到巴特地图的代码:
(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中提出一种更优雅,更希望成语的方法吗?
最佳答案
(into {} (for [foo foos
{bar-id :id :as bar} (:bars foo)
{baz-id :id} (:bazes bar)]
{baz-id bar-id}))