我发现自己总是这样做。我一直在考虑编写一个宏/函数来使这种事情变得更容易,但我发现我可能正在重新发明轮子。
是否有现成的功能可以让我更简洁地完成同样的事情?
(defun remove-low-words (word-list)
"Return a list with words of insufficient score removed."
(let ((result nil))
(dolist (word word-list)
(when (good-enough-score-p word) (push word result)))
result))
答案 0 :(得分:22)
有几种内置的方法可以做到这一点。一种方法是:
(remove-if-not 'good-enough-score-p word-list)
另一个:
(loop for word in word-list
when (good-enough-score-p word)
collect word)
而另一个:
(mapcan (lambda (word)
(when (good-enough-score-p word)
(list word)))
word-list)
等等......还有SERIES和Iterate。 Iterate版本与LOOP版本相同,但SERIES版本很有趣:
(collect (choose-if 'good-enough-score-p (scan word-list))))
所以,是的,你很可能重新发明一些轮。 : - )
答案 1 :(得分:6)
您想要的功能是remove-if-not
,它是内置的。
(defun remove-low-words (word-list)
(remove-if-not #'good-enough-score-p word-list))
如果您觉得自己正在重新发明与列表有关的内容,那么您可能就是这样。检查Hyperspec以查看。
答案 2 :(得分:-2)
有几种方法可以做到这一点。首先,也许最容易,你可以递归地做。
(defun remove-low-words (word-list)
(if (good-enough-score-p (car word-list))
(list word (remove-low-words (cdr word-list)))
(remove-low-words (cdr word-list))))
您也可以使用mapcar
和reduce
执行此操作,其中前者可以构建一个列表,其中包含由nil
替换的失败元素,后者可用于过滤{ {1}}。
对于“过滤器”宏或函数来说,它都是一个很好的候选者,它接受一个列表并返回由某个谓词过滤的列表。