Итерация списка Лиспа

У меня есть функция, которая получает x (значение) и xs (список) и удаляет все значения, превышающие x, из списка. Ну, это не работает, ты можешь сказать мне, почему?

(defun biggerElems(x xs) 
  (let ((xst))
    (dolist (elem xs)
      (if (> x elem)
          (setf xst (remove elem xs))))
    xst))
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
3 230
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Я думаю, что это неправильная строка:

(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))))))

@ Луис Оливейра

Это решение контрастирует с тем, что написано в вопросе. Если бы нам нужно было сделать что-то более сложное, важно основываться на рекурсивном подходе к управлению списками.

То, что вы МОЖЕТЕ использовать рекурсию в Лиспе, не означает, что это «путь Лиспа». В Лиспе есть несколько механизмов для этого (как показано в другом месте), и все они идиоматичны. Рекурсивный метод просто самый примитивный.

Will Hartung 23.09.2008 02:43

Самый краткий 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 которых больше).

Другие вопросы по теме