我正在尝试编写一个返回列表中原子列表的函数,可以说我有一个列表,其中既有原子又有一个列表,当我运行该函数时,它应该返回一个原子列表。
例如:
(func '(2 34 5 (12) 7 (A B C) +))
-> (2 34 7 +)
我想尝试结果中的参数是否为真,这样当我运行时:
(ATOM ( (func '(2 34 5 (12) 7 (A B C) +)) )
->T
关于我如何去做的任何想法?书籍或参考资料?
我正在尝试编写一个返回列表中原子列表的函数,可以说我有一个列表,其中既有原子又有一个列表,当我运行该函数时,它应该返回一个原子列表。
例如:
(func '(2 34 5 (12) 7 (A B C) +))
-> (2 34 7 +)
我想尝试结果中的参数是否为真,这样当我运行时:
(ATOM ( (func '(2 34 5 (12) 7 (A B C) +)) )
->T
关于我如何去做的任何想法?书籍或参考资料?
使用标准 CL 函数,
[3]> (remove-if-not #'atom '(1 2 (12) +))
(1 2 +)
[6]> (every #'atom (remove-if-not #'atom '(1 2 (12) +)))
T
如果您想自己编写它们,您可以融合#'atom
in 并制作两个专门的函数,比如remove-atoms
and every-is-atom
。但是“原子”是一个内置函数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))))))
这使用破坏性更新以自上而下的方式构建结果列表,这并不违反这里的函数式编程精神,因为它是在本地使用的,作为一种实现技术。这可以看作是来自其他答案的通用函数尾递归模数代码的 Common-LISP 特定翻译。
第二个功能:
(defun every-is-atom (xs)
(dolist (x xs T)
(if (not (atom x))
(return-from every-is-atom NIL))))
所以你想要一个只返回作为参数传递的列表中存在的原子值的函数?
像这样?
(defun func (lst)
(cond
((null lst) '())
((atom (first lst))
(cons (first lst) (func (rest lst))))
(t (func (rest lst)))))
不是专门针对 Common lisp,但在我看来仍然是一本好书:SICP