在Clojure中对象层次结构中的子对象上重复出现
我有以下问题:在Clojure中对象层次结构中的子对象上重复出现,clojure,Clojure,我有以下问题: (def relations1 '((child-of peter carl) (child-of carl herb) (peter x 0 y 0 age 6) (carl x 1 y 1 age 36) (herb x 2 y 2 age 66))) 如果父对象移动,则子对象将移动相同的距离,因此如果新关系声明herb和peter已移动,则我希望以相同的偏移量更新relation2中不存在的子对象,但那些存在的子对象将不受
(def relations1
'((child-of peter carl)
(child-of carl herb)
(peter x 0 y 0 age 6)
(carl x 1 y 1 age 36)
(herb x 2 y 2 age 66)))
如果父对象移动,则子对象将移动相同的距离,因此如果新关系声明herb和peter已移动,则我希望以相同的偏移量更新relation2中不存在的子对象,但那些存在的子对象将不受影响。因此,在下一阶段:
(def relations2
'((herby2 x 3 y 2.5 age 66)
(pete2 x 0 y 0 age 6)))
我首先将关系1与关系2中的关系匹配:
(def matches
'( ((herb x 2 y 2 age 66)
(herb2 x 3 y 2.5 age 66)),
((peter x 0 y 0 age 6)
(peter2 x 0 y 0 age 6))))
我想检查匹配的人,更新他们自己的新位置(同时保留他们以前的姓名和年龄),并递归检查他们是否有孩子更新他们的位置。我试过了,但也被困在如何在孩子们身上重现的问题上:
(def update-parents [matches, relations1]
(loop [rest matches
all relations1
result ()]
(if (empty? rest)
result
(let [[head & others] rest
r1 (first head)
r2 (second head)
exists (map first r2)
children (map second (filter #(and (= (first r1) (last %)) (= 'child-of (first %))) all))]
(if (some #(= (first r1) %) exists)
(recur others (concat (update r1 r2) (recur ???)); if it is already there, update position and its children's
; if it's not there, then ignore
)
所以最终的结果应该是这样
(def result
'((herb x 3 y 2.5 age 66)
(peter x 0 y 0 age 6)
(carl x 2 y 1.5 age 36) ))
我有两个主要问题:
您可以通过将要删除的内容放入一个集合并使用
(删除#(包含集合%)列表)
或更惯用的(删除集合列表)
从列表中删除内容(即创建一个没有这些内容的新列表),因为集合作为一个函数运行。(“过滤”的作用类似,但保留谓词同意的内容。)
循环
…重复
特殊形式将仅从尾部位置重复,这可能是对给定问题的挑战。但如果您不需要尾部调用优化,那么函数可以简单地调用自身
在任何情况下,如果要使用任何类型的递归,都需要一个树形数据结构,其中每个节点都类似于根。关系1
中的“事实袋”将很难处理
查看clojure.walk
和clojure.zip
作为树数据结构的固定解决方案
另外,以“自下而上”的方式在REPL中工作也可能会有所帮助,可以在砂锅菜之前处理配料。您可能对处理树状数据结构的Tupelo Forest库感兴趣:谢谢!但是为了得到
集合
,我需要先做一个过滤器,对吗?此外,我是否应该维护一个树,在其中遍历最新的关系集,并首先使用“关系的子对象”更新树,以便更容易找到它们的子对象?(删除列表中的集合)
似乎不适用于例如(定义集合(pete jo))(定义列表(alvin))
它给了我一个错误clojure.lang.PersistentList无法转换为类clojure.lang.IFn
我发现了它是如何工作的,您需要将它放入(删除(设置)列表)
才能工作: