Clojure函数定义:路径树
我想定义一个函数Clojure函数定义:路径树,clojure,tree,functional-programming,Clojure,Tree,Functional Programming,我想定义一个函数f,它返回一棵树(作为嵌套映射),给定通过该树的路径序列 e、 g 假设所有向量都表示源于同一根的路径 如何在一次过程中从功能上定义此函数 我对与之相反的行为感兴趣。我会使用以下地图: (def paths [[:a :b :c] [:a :b :d] [:b :d] [:b :e] [:b :e :a]]) (defn update-with-path [tree-map pa
f
,它返回一棵树(作为嵌套映射),给定通过该树的路径序列
e、 g
假设所有向量都表示源于同一根的路径
如何在一次过程中从功能上定义此函数
我对与之相反的行为感兴趣。我会使用以下地图:
(def paths [[:a :b :c]
[:a :b :d]
[:b :d]
[:b :e]
[:b :e :a]])
(defn update-with-path
[tree-map path-vec]
(assoc-in tree-map path-vec nil) )
(defn build-tree [paths]
(reduce
update-with-path
{} paths )
)
(deftest t-global
(is= {:a nil} (update-with-path {} [:a]))
(is= {:a {:b nil}} (update-with-path {} [:a :b]))
(is= {:a {:b {:c nil}}} (update-with-path {} [:a :b :c]))
(is= (build-tree paths)
{ :a
{ :b
{ :c nil
:d nil}}
:b
{
:d nil
:e
{ :a nil }}}
)
)
(ns xyz...
(:require
[tupelo.core :as t] ))
(t/refer-tupelo)
(def t1 (build-tree paths))
(def cum (atom []))
(defn walker [path tree]
(if (nil? tree)
(swap! cum t/append path)
(doseq [key (keys tree)]
(walker (t/append path key) (t/grab key tree)))))
(walker [] t1)
(spyx @cum)
=> [[:a :b :c] [:a :b :d] [:b :d] [:b :e :a]]
在assoc中使用地图很容易。所有叶值的值均为nil
,而非叶值的值均为map。此外,使用嵌套映射结构意味着我们不必担心重复
您可以找到所有叶节点,如下所示:
(def paths [[:a :b :c]
[:a :b :d]
[:b :d]
[:b :e]
[:b :e :a]])
(defn update-with-path
[tree-map path-vec]
(assoc-in tree-map path-vec nil) )
(defn build-tree [paths]
(reduce
update-with-path
{} paths )
)
(deftest t-global
(is= {:a nil} (update-with-path {} [:a]))
(is= {:a {:b nil}} (update-with-path {} [:a :b]))
(is= {:a {:b {:c nil}}} (update-with-path {} [:a :b :c]))
(is= (build-tree paths)
{ :a
{ :b
{ :c nil
:d nil}}
:b
{
:d nil
:e
{ :a nil }}}
)
)
(ns xyz...
(:require
[tupelo.core :as t] ))
(t/refer-tupelo)
(def t1 (build-tree paths))
(def cum (atom []))
(defn walker [path tree]
(if (nil? tree)
(swap! cum t/append path)
(doseq [key (keys tree)]
(walker (t/append path key) (t/grab key tree)))))
(walker [] t1)
(spyx @cum)
=> [[:a :b :c] [:a :b :d] [:b :d] [:b :e :a]]
然后修改树创建代码,创建一棵带有向量叶的新树:
(defn update-with-path-2
[tree-map path-vec]
(assoc-in tree-map path-vec path-vec))
(defn build-tree-2 [paths]
(reduce
update-with-path-2
{} paths)
)
(spyx (build-tree-2 @cum))
=> {:a {:b {:c [:a :b :c],
:d [:a :b :d]}},
:b {:d [:b :d],
:e {:a [:b :e :a]}}}
此代码使用。如何修改此定义以包含结果映射中每个路径叶的原始路径向量(例如,[:a:b:c]来代替
nil
?在用路径更新的定义中,将nil替换为对路径向量的引用?对不起,@alan,我无意中点击了[enter]很早。我现在正在准备例子。