Frage

Ich habe eine Funktion, die x(einen Wert) und xs(eine Liste) abruft und alle Werte, die größer als x sind, aus der Liste entfernt.Nun, es funktioniert nicht. Können Sie mir sagen, warum?

(defun biggerElems(x xs) 
  (let ((xst))
    (dolist (elem xs)
      (if (> x elem)
          (setf xst (remove elem xs))))
    xst))
War es hilfreich?

Lösung

Ich denke, dass diese Zeile nicht stimmt:

(setf xst (remove elem xs))))

Das erste Argument dazu setf ist der Ort, gefolgt vom Wert.Es sieht so aus, als ob Sie es verkehrt herum haben (und xst entweder nil oder nicht initialisiert).

Möglicherweise fällt es Ihnen leichter, dies zu tun:

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

Andere Tipps

Prägnanteste AFAIK:

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

Wenn eine neue Liste zurückgegeben wird, werden alle Elemente y aus xs entfernt, für die

(< y x)

oder mit dem berühmten LOOP:

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

Es hat so funktioniert:

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

Wofür war das „#“?Es wurde nicht damit kompiliert.

Wenn Sie dies auf die Lisp-Art tun möchten, können Sie die Rekursion verwenden, um die neue Liste zurückzugeben:

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

@Luís Oliveira

Diese Lösung steht im Gegensatz zu der in der Frage veröffentlichten.Hätten wir etwas etwas Komplizierteres tun müssen, wäre es wichtig, sich mit dem rekursiven Ansatz zur Manipulation von Listen vertraut zu machen.

@Ben:Es ist nicht der setf-Aufruf, der falsch ist – das Problem ist, dass er xs nicht aktualisiert.

dh:xst wird auf xs gesetzt, wobei das Element entfernt wird, aber xs wird nicht aktualisiert.Wenn ein zweites Element entfernt werden soll, hat xst das erste wieder darin.

Sie müssten xst an xs binden und das xs im Remove-Aufruf durch xst ersetzen.Dies würde dann alle Elemente entfernen, die x größer sind als.dh:

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

Es könnte etwas schneller sein, xst auf (copy-list xs) zu setzen und dann „delete“ anstelle von „remove“ zu verwenden (delete ist destruktiv ...Abhängig von Ihrer Implementierung ist dies möglicherweise schneller als das Entfernen.Da Sie dies mehrmals aufrufen, erzielen Sie möglicherweise eine bessere Leistung, wenn Sie die Liste einmal kopieren und anschließend destruktiv daraus löschen.

Alternative:

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

Wenn ich auf Ihren ursprünglichen Beitrag zurückblicke, ist er etwas verwirrend ...Sie sagen, Sie entfernen alle Elemente, die größer als x sind, aber Ihr Code scheint zu versuchen, alle Elemente zu entfernen, die größer als x sind.Die Lösungen, die ich geschrieben habe, geben alle Elemente zurück, die größer als x sind (d. h.:entferne alle Elemente x ist größer als).

Wofür war das „#“?Es kompilierte nicht damit.

Tippfehler.Normalerweise bezeichnet man Funktionen mit #' (wie (remove-if #'oddp list)), aber beim Bearbeiten habe ich vergessen, das „#“ zu entfernen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top