我有一个获取x(值)和xs(列表)的函数,并从列表中删除大于x的所有值。好吧它不起作用,你能告诉我为什么吗?
(defun biggerElems(x xs)
(let ((xst))
(dolist (elem xs)
(if (> x elem)
(setf xst (remove elem xs))))
xst))
答案 0 :(得分:5)
我认为这条线路不对:
(setf xst (remove elem xs))))
setf
的第一个参数是地点,后跟值。看起来你倒退了(xst
是nil
或未初始化)。
您可能会发现这样做更容易:
(defun biggerElems (x xs)
(remove-if (lambda (item) (> item x)) xs))
答案 1 :(得分:4)
最简洁的AFAIK:
(defun bigger-elements (x xs) (remove x xs :test #'<))
返回一个新的列表,它会从xs中删除所有元素y
(< y x)
或使用着名的LOOP:
(defun bigger-elements-2 (x xs)
(loop for e in xs
unless (< e x)
collect e))
答案 2 :(得分:1)
它的工作原理如下:
(defun filterBig (x xs)
(remove-if (lambda (item) (> item x)) xs))
'#'是什么?它没有用它编译。</ p>
答案 3 :(得分:1)
如果你想用Lisp Way做这个,你可以使用递归来返回新的列表:
(defun biggerElems (x xs)
(cond ((null xs) NIL)
((< x (car xs))
(biggerElems x (cdr xs)))
(t
(cons (car xs) (biggerElems x (cdr xs))))))
@LuísOliveira
此解决方案与问题中发布的解决方案形成鲜明对比。如果我们需要做一些稍微复杂的事情,那么建立基于操纵列表的递归方法是很重要的。
答案 4 :(得分:1)
@Ben:这不是setf调用错误 - 问题是他没有更新xs。
ie:xst被设置为xs并删除了元素,但xs没有被更新。如果要删除第二个元素,xst将返回第一个元素。
您需要将xst绑定到xs,并使用xst替换remove调用中的xs。然后,这将删除x大于的所有元素。即:
(defun biggerElems(x xs)
(let ((xst xs))
(dolist (elem xs)
(when (> x elem)
(setf xst (remove elem xst))))
xst))
将xst设置为(copy-list xs)然后使用delete而不是remove(删除是破坏性的......可能会稍快一些......取决于你的实现,它可能比删除更快。因为你调用了这个多次,你可以获得更好的性能,复制一次列表并破坏性删除它。)
可替换地:
(defun bigger-elems (x xs) ; I prefer hyphen separated to camelCase... to each his own
(loop for elem in xs when (<= x elem) collect elem))
回顾一下你原来的帖子,这有点令人困惑......你说你删除了大于x的所有元素,但是你的代码看起来正试图删除所有x大于的元素。我写的解决方案返回所有大于x的元素(即:删除所有元素x大于)。
答案 5 :(得分:0)
'#'是什么?它没有 用它编译。</ p>
错字。通常情况下,您使用#'
(例如(remove-if #'oddp list)
)来引用功能,但在我编辑时,我忘记删除“#”。