2010-11-22 12 views

Antwort

25

Wenn Sie

(require 'cl) 

dann können Sie die Common Lisp Funktion reduce verwenden. Übergeben Sie das Schlüsselwortargument :from-end t für foldr.

ELISP> (reduce #'list '(1 2 3 4)) 
(((1 2) 3) 4) 

ELISP> (reduce #'list '(1 2 3 4) :from-end t) 
(1 (2 (3 4))) 
12

Da Emacs-24.3 wir die Verwendung von cl-lib über cl empfehlen (die für die Entfernung in ferner Zukunft geplant ist), so dass es sein würde:

(require 'cl-lib) 
(cl-reduce #'list '(1 2 3 4)) 

und seit Emacs-25, Sie kann auch das seq Paket für das verwenden:

(require 'seq) 
(seq-reduce #'list '(1 2 3 4)) 
+3

Dieses sollte besser in als eine separate Antwort einen Kommentar zu Gareth Rees' Antwort sein, ihre eigenes Recht. – Thomas

+0

@Thomas Es ist nicht möglich, mehrzeilige Kommentare mit Beispielen auf SO zu schreiben. – ceving

5

Common Lisp library viele sequence functions wie Mapping bietet, fil teren, falten, suchen und sogar sortieren. CL-Bibliothek wird standardmäßig mit Emacs ausgeliefert, also sollten Sie sich daran halten. Ich mag jedoch wirklich dash.el Bibliothek, weil es enorme Mengen von Funktionen für Listen- und Baummanipulationen bietet. Es unterstützt auch anaphoric macros und ermutigt funktionale Programmierung, die Code prägnant und elegant macht.

Haskells Falten entsprechen dash.el Faltungen:

Summe eines Bereichs von 1 bis 10 unter Verwendung von Falten in dieser wie in Haskell und dash.el aussehen könnte:

foldl (+) 0 [1..10] -- Haskell 
(-reduce-from '+ 0 (number-sequence 1 10)) ; Elisp 

Sie wissen wahrscheinlich, dass Falten sehr allgemein gehalten sind, und es ist möglich, Karten und Filter über Falten zu implementieren . Zum Beispiel würde es ermöglichen, jedes Element von 2, Haskells currying und Abschnitte zu erhöhen für terse Code, aber in Elisp würden Sie in der Regel schreiben ausführliche Wegwerf-Lambda-Ausdrücke wie folgt aus:

foldr ((:) . (+2)) [] [1..10] -- Haskell 
(-reduce-r-from (lambda (x acc) (cons (+ x 2) acc)) '() (number-sequence 1 10)) ; Elisp 

Ratet mal, was es in dash.el nicht notwendig ist, mit anaphorischen Makros, die eine spezielle Syntax ermöglichen, indem sie Variablen eines Lambda als Abkürzungen wie it und acc in Faltungen offenlegen. Anaphorische Funktionen beginnen mit zwei Strichen statt 1:

(--reduce-r-from (cons (+ it 2) acc) '() (number-sequence 1 10)) 

Es gibt viele faltenartige Funktionen in dash.el:

;; Count elements matching a predicate 
(-count 'evenp '(1 2 3 4 5)) ; 2 
;; Add/multiply elements of a list together 
(-sum '(1 2 3 4 5)) ; 15 
(-product '(1 2 3 4 5)) ; 120 
;; Find the smallest and largest element 
(-min '(3 1 -1 2 4)) ; -1 
(-max '(-10 0 10 5)) ; 10 
;; Find smallest/largest with a custom rule (anaphoric versions) 
(--min-by (> (length it) (length other)) '((1 2 3) (4 5) (6))) ; (6) 
(--max-by (> (length it) (length other)) '((1 2 3) (4 5) (6))) ; (1 2 3) 
Verwandte Themen