Вопрос
У меня есть функция, которая получает x(значение) и xs(список) и удаляет из списка все значения, превышающие x.Ну, это не работает, можете сказать мне, почему?
(defun biggerElems(x xs)
(let ((xst))
(dolist (elem xs)
(if (> x elem)
(setf xst (remove elem xs))))
xst))
Решение
Я думаю, что эта строка неверна:
(setf xst (remove elem xs))))
Первый аргумент для setf
это место, за которым следует значение.Похоже, у вас все наоборот (и xst
либо nil
или неинициализированный).
Возможно, вам будет проще сделать это:
(defun biggerElems (x xs)
(remove-if (lambda (item) (> item x)) 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))
Это работало так:
(defun filterBig (x xs)
(remove-if (lambda (item) (> item x)) xs))
Для чего нужен был знак «#»?Он не скомпилировался с ним.
Если вы хотите сделать это с помощью Lisp, вы можете использовать рекурсию для возврата нового списка:
(defun biggerElems (x xs)
(cond ((null xs) NIL)
((< x (car xs))
(biggerElems x (cdr xs)))
(t
(cons (car xs) (biggerElems x (cdr xs))))))
@Луис Оливейра
Это решение контрастирует с решением, опубликованным в вопросе.Если бы нам нужно было сделать что-то более сложное, важно было бы опираться на рекурсивный подход к манипулированию списками.
@Бен:Неправильный не вызов setf — проблема в том, что он не обновляет xs.
то есть:xst устанавливается на xs с удаленным элементом, но xs не обновляется.Если второй элемент должен быть удален, xst вернет в него первый элемент.
вам нужно будет связать xst с xs и заменить xs в вызове удаления на xst.Затем это приведет к удалению всех элементов, которые больше x.то есть:
(defun biggerElems(x xs)
(let ((xst xs))
(dolist (elem xs)
(when (> x elem)
(setf xst (remove elem xst))))
xst))
Возможно, было бы немного быстрее установить для xst значение (список копирования xs), а затем использовать удаление вместо удаления (удаление разрушительно...в зависимости от вашей реализации это может быть быстрее, чем удаление.Поскольку вы вызываете это несколько раз, вы можете повысить производительность, скопировав список один раз и удалив его из него).
Альтернативно:
(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 больше).
Для чего нужен был знак «#»?Это не компилировало с этим.
Опечатка.Обычно вы ссылаетесь на функции с #'
(нравиться (remove-if #'oddp list)
), но когда я редактировал, я забыл удалить «#».