Pregunta

Tengo una función que obtiene x(un valor) y xs(una lista) y elimina todos los valores que son mayores que x de la lista.Bueno, no funciona, ¿puedes decirme por qué?

(defun biggerElems(x xs) 
  (let ((xst))
    (dolist (elem xs)
      (if (> x elem)
          (setf xst (remove elem xs))))
    xst))
¿Fue útil?

Solución

Creo que es esta línea la que no está bien:

(setf xst (remove elem xs))))

El primer argumento para setf es el lugar, seguido del valor.Parece que lo tienes al revés (y xst es cualquiera nil o no inicializado).

Puede que le resulte más fácil hacer esto:

(defun biggerElems (x xs)
  (remove-if (lambda (item) (> item x)) xs))

Otros consejos

Lo más conciso que yo sepa:

(defun bigger-elements (x xs) (remove x xs :test #'<))

al devolver una lista nueva, elimina todos los elementos y de xs para los cuales

(< y x)

o usando el famoso LOOP:

(defun bigger-elements-2 (x xs) 
  (loop for e in xs
        unless (< e x)
        collect e))

Funcionó así:

(defun filterBig (x xs)
  (remove-if (lambda (item) (> item x)) xs))

¿Para qué fue el '#'?No se compiló con él.

Si desea hacer esto a la manera Lisp, puede usar la recursividad para devolver la nueva lista:

(defun biggerElems (x xs)
  (cond ((null xs) NIL)
        ((< x (car xs))
         (biggerElems x (cdr xs)))
       (t
        (cons (car xs) (biggerElems x (cdr xs))))))

@Luis Oliveira

Esta solución contrasta con la publicada en la pregunta.Si tuviéramos que hacer algo un poco más complicado, es importante basarnos en el enfoque recursivo para manipular listas.

@Ben:No es la llamada a setf la que está mal; el problema es que no está actualizando xs.

es decir:xst se establece en xs con el elemento eliminado, pero xs no se actualiza.Si se va a eliminar un segundo elemento, xst tendrá el primero nuevamente.

necesitaría vincular xst a xs y reemplazar xs en la llamada de eliminación con xst.Esto eliminaría todos los elementos que x sean mayores que.es decir:

(defun biggerElems(x xs)
  (let ((xst xs))
    (dolist (elem xs)
      (when (> x elem)
        (setf xst (remove elem xst))))
    xst))

Podría ser un poco más rápido configurar xst en (copiar lista xs) y luego usar eliminar en lugar de eliminar (eliminar es destructivo...Dependiendo de su implementación, puede ser más rápido que eliminar.Dado que llama a esto varias veces, puede obtener un mejor rendimiento copiando la lista una vez y eliminándola de forma destructiva).

Alternativamente:

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

Volviendo a leer tu publicación original, es un poco confuso...dices que eliminas todos los elementos mayores que x, pero parece que tu código está intentando eliminar todos los elementos que x son mayores.Las soluciones que escribí devuelven todos los elementos mayores que x (es decir:eliminar todos los elementos x es mayor que).

¿Para qué fue el '#'?No se compilaron con eso.

Error de tipografía.Normalmente te refieres a funciones con #' (como (remove-if #'oddp list)), pero cuando estaba editando, olvidé eliminar el '#'.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top