




Я думаю, что это неправильная строка:
(setf xst (remove elem xs))))
Первый аргумент setf - это место, за которым следует значение. Похоже, у вас это наоборот (а xst либо nil, либо неинициализированный).
Возможно, вам будет проще сделать это:
(defun biggerElems (x xs)
(remove-if (lambda (item) (> item x)) xs))
Это работало так:
(defun filterBig (x xs)
(remove-if (lambda (item) (> item x)) xs))
Для чего был знак "#"? Он не компилировался с этим.
What was the '#' for? It didn't compile with it.
Опечатка. Обычно вы ссылаетесь на функции с #' (например, (remove-if #'oddp list)), но когда я редактировал, я забыл удалить '#'.
Если вы хотите сделать это по-лисповски, вы можете использовать рекурсию для возврата нового списка:
(defun biggerElems (x xs)
(cond ((null xs) NIL)
((< x (car xs))
(biggerElems x (cdr xs)))
(t
(cons (car xs) (biggerElems x (cdr xs))))))
@ Луис Оливейра
Это решение контрастирует с тем, что написано в вопросе. Если бы нам нужно было сделать что-то более сложное, важно основываться на рекурсивном подходе к управлению списками.
Самый краткий AFAIK:
(defun bigger-elements (x xs) (remove x xs :test #'<))
возвращая свежий список, он удаляет все элементы y из xs, для которых
(< y x)
или используя знаменитый LOOP:
(defun bigger-elements-2 (x xs)
(loop for e in xs
unless (< e x)
collect e))
@Ben: Это не вызов setf неправильный - проблема в том, что он не обновляет xs.
то есть: xst устанавливается в xs с удаленным элементом, но xs не обновляется. Если второй элемент должен быть удален, xst вернет в него первый.
вам нужно будет привязать xst к xs и заменить xs в вызове remove на xst. Тогда это удалит все элементы 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 которых больше).
То, что вы МОЖЕТЕ использовать рекурсию в Лиспе, не означает, что это «путь Лиспа». В Лиспе есть несколько механизмов для этого (как показано в другом месте), и все они идиоматичны. Рекурсивный метод просто самый примитивный.