Gibt es eine Funktion wie "assoc", die alle übereinstimmenden Werte zurückgibt?

7

Die assoc KEY LISTFunktion gibt das erste Element eines alistAutos zurück, dessen gleich ist KEY.

Gibt es eine eingebaute Emacs Lisp-Funktion, die alle Elemente zurückgibt, alistderen Autos gleich sind KEY, als Unteralist oder Werteliste? Schließlich ist es nicht erforderlich, dass ein alisteindeutiger Schlüssel vorhanden ist.

Das ist,

(assoc foo '((foo . 5) (bar . 6) (foo . 7))) = '(foo . 5)

Aber,

(assoc-all foo '((foo . 5) (bar . 6) (foo . 7))) = '((foo . 5) (foo . 7))
Matthew Piziak
quelle

Antworten:

6

Etwas wie das?

(require 'cl-lib)

(cl-remove-if-not (apply-partially #'equal 'foo)
                  '((foo . 5) (bar . 6) (foo . 7))
                  :key #'car)

=> ((foo . 5) (foo . 7))
(defun assoc-all (key list &optional testfn)
  "Like `assoc', but returns the list of all matching elements."
  (cl-remove-if-not (apply-partially (or testfn #'equal) key)
                    list :key #'car))
Phils
quelle
1
Bitte stellen Sie Funktionsnamen voran, #'anstatt nur 'dem Compiler mitzuteilen, dass dies eine Funktionsreferenz ist (funktioniert für beide 'equalund 'car).
Damien Cassou
Erledigt; Obwohl dies meines Wissens in diesem Fall völlig überflüssig ist - es würde nur irgendetwas beeinflussen, wenn es definiert wäre caroder equalnicht, nein?
Phils
Ist nach Ihrer Definition #'immer redundant, da Sie nur auf definierte Funktionen verweisen sollen :-). Ich denke, es ist eine gute Angewohnheit, Ihre Funktionsreferenzen immer scharf zu zitieren. Und wer weiß, der Byte-Compiler könnte diese Informationen eines Tages verwenden, um Ihren Code zu optimieren :-).
Damien Cassou
5

Eine andere Lösung mit seq-filter:

(seq-filter (lambda (elt) (equal (car elt) 'foo))
            '((foo . 5) (bar . 6) (foo . 7)))
Damien Cassou
quelle