Идиома Common lisp - есть ли способ лучше?
-
09-06-2019 - |
Вопрос
Я ловлю себя на том, что постоянно занимаюсь подобными вещами.Я подумывал о написании макроса / функции, чтобы упростить подобные вещи, но мне приходит в голову, что я, вероятно, изобретаю велосипед заново.
Есть ли существующая функция, которая позволит мне выполнить то же самое более кратко?
(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))
Решение
Есть несколько встроенных способов сделать это. Один из способов будет:
(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)
И т.д. net / project / iterate / "rel =" noreferrer "> Iterate . Версия Iterate идентична версии LOOP, но версия SERIES интересна:
(collect (choose-if 'good-enough-score-p (scan word-list))))
Итак, да, вы, скорее всего, заново изобретете колесо . : -)
Другие советы
Функция, которую вы хотите, это remove-if-not
, который является встроенным.
(defun remove-low-words (word-list)
(remove-if-not #'good-enough-score-p word-list))
Если вам кажется, что вы заново изобретаете что-то, связанное со списками, то, скорее всего, так оно и есть.Проверьте Hyperspec, чтобы увидеть.
Есть несколько способов сделать это. Во-первых, и, вероятно, проще всего, вы можете сделать это рекурсивно.
(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
и redu
, где первый может создать вам список с ошибочными элементами, замененными на nil
и последний может быть использован для фильтрации nil
.
Любой из них был бы хорошим кандидатом на "фильтр" макрос или функция, которая принимает список и возвращает список, отфильтрованный по некоторому предикату.