Clojure映射转换(树中的子对象到父对象)
假设我有树中节点及其子节点的以下映射:Clojure映射转换(树中的子对象到父对象),clojure,Clojure,假设我有树中节点及其子节点的以下映射: (def a {0 [], 1 [], 2 [0, 1]}) 对应于根节点2和两个叶节点0和1作为节点2子节点的树 我如何把它变成父亲的地图,或者,更好的是,用父亲来装饰它。例如,到达以下父亲地图: {0 2, 1 2, 2 nil} ; each node only has one father at most 或者,更好的是,在下面的地图上,结合了孩子和父亲: {0 [[] 2], 1 [[] 2], 2 [[0,1] nil]} 第一位: (d
(def a {0 [], 1 [], 2 [0, 1]})
对应于根节点2和两个叶节点0和1作为节点2子节点的树
我如何把它变成父亲的地图,或者,更好的是,用父亲来装饰它。例如,到达以下父亲地图:
{0 2, 1 2, 2 nil} ; each node only has one father at most
或者,更好的是,在下面的地图上,结合了孩子和父亲:
{0 [[] 2], 1 [[] 2], 2 [[0,1] nil]}
第一位:
(def a {0 [], 1 [], 2 [0, 1]})
(defn parent-map [m]
(reduce
(fn [x [k v]]
(into x (zipmap v (repeat k)))) {} m))
(def parent (parent-map a))
parent
=> {1 2, 0 2}
(parent 1)
=> 2
(parent 2)
=> nil
因此,不需要在父映射中显式地使用2 nil
第二位:
(defn parent-child-map [m]
(let [parent (parent-map m)]
(reduce
(fn [x [k v]]
(assoc x k [(m k) (parent k)])) {} m)))
(parent-child-map a)
=> {2 [[0 1] nil], 1 [[] 2], 0 [[] 2]}
更有趣的是:
(def b {0 [], 1 [], 2 [], 3 [], 4 [0 1 2], 5 [3], 6 [4 5]})
(parent-child-map b)
=>
{6 [[4 5] nil],
5 [[3] 6],
4 [[0 1 2] 6],
3 [[] 5],
2 [[] 4],
1 [[] 4],
0 [[] 4]}
是什么指定了根,它是最后一个吗?我想根是唯一没有父母的根,也就是说,不是某人的孩子。没有父母的根,你可以假设只有一个根(一棵树,不是一片森林)。谢谢你的回答,我希望我能接受这两个,但我最终接受了莫比的,因为一旦我得到它,我的理解似乎就更清楚了。
(defn parents [m]
(let [plist (into {} (for [[k v] m vv v] [vv k]))]
(into {} (map (fn [[k v]] [k [v (plist k)]]) m))))
(parents a)
=> {0 [[] 2], 1 [[] 2], 2 [[0 1] nil]}