【发布时间】:2014-09-03 10:02:20
【问题描述】:
要在 Lisp 中折叠一个平面列表,请使用 reduce:
* (reduce #'+ '(1 2 3 4 5))
15
但是,如果我有一个任意复杂的树,并且我想对每个元素应用一个函数怎么办?所以折叠'(1 (2) (3 (4) 5)) 仍然会给15?我尝试使用reduce,但我必须提供一个自定义函数,这有点违背了目的:
(defun tree+ (a b)
(cond ((null b) 0)
((atom b) (+ a b))
(t (+ (tree+ a (car b))
(tree+ 0 (cdr b))))))
(reduce #'tree+ '(1 (2) (3 (4) 5)) :initial-value 0) ; returns 15
当然我可以先把列表展平,但是reduce是一个通用函数,有时你必须保留原始序列的结构和顺序。例如,map 和filter 可以用reduce 实现。如果我想基于reduce编写my-map的实现,那么:
(my-map '1+ '(1 (2 (3) 4) 5)) ; outputs '(2 (3 (4) 5) 6)
如何在树形结构上使用reduce?在树上应用二元函数的最通用方法是什么?
【问题讨论】:
-
@uselpa,查看修复,扁平化并不通用
-
这是关于 Scheme 的,但我在 Counting elements of a list and sublists 中实现了一个 treeduce 函数,它展示了如何为树概括折叠。
-
请注意,您的示例
(1 (2 (3) 4) 5)不是“整数树”(一些叶子是nil),而是“嵌套整数列表”。
标签: tree lisp common-lisp fold