我正在尝试编写一个返回列表中的原子列表的函数,假设我有一个列表,其中包含原子和列表,当我运行该函数时,它应该返回一个原子列表。
例如:
(func '(2 34 5 (12) 7 (A B C) +))
-> (2 34 7 +)
我想尝试结果中的参数是否为真,这样当我运行时:
(ATOM ( (func '(2 34 5 (12) 7 (A B C) +)) )
->T
关于我如何去做的任何想法?书籍或参考文献?
答案 0 :(得分:3)
使用标准CL功能
[3]> (remove-if-not #'atom '(1 2 (12) +))
(1 2 +)
[6]> (every #'atom (remove-if-not #'atom '(1 2 (12) +)))
T
如果您想自己编写,可以融合#'atom
并制作两个专门的功能,比如说remove-atoms
和every-is-atom
。但“atom”是built-in function atom
的名称。
编写第一种方法的一种方法是
(defun remove-atoms (xs &aux (ys (list 1)))
(let ((p ys))
(dolist (x xs (cdr ys))
(if (atom x) (setf (cdr p) (list x) p (cdr p))))))
这使用破坏性更新以自上而下的方式构建结果列表,这不违反函数式编程 here 的精神,因为它在本地使用,作为一种实现技术。这可以被视为来自另一个答案的一般功能tail-recursive-modulo-cons代码的Common-LISP特定翻译。
第二个功能:
(defun every-is-atom (xs)
(dolist (x xs T)
(if (not (atom x))
(return-from every-is-atom NIL))))
答案 1 :(得分:2)
所以你想要一个只返回作为参数传递的列表中存在的原子值的函数吗?
喜欢这个吗?
(defun func (lst)
(cond
((null lst) '())
((atom (first lst))
(cons (first lst) (func (rest lst))))
(t (func (rest lst)))))
不是专门用于普通的lisp,但在我看来仍然是一个很好的阅读:SICP