2010-11-22 38 views

Trả lời

25

Nếu bạn

(require 'cl) 

sau đó bạn có thể sử dụng chức năng Common Lisp reduce. Vượt qua đối số từ khóa :from-end t cho 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

Kể từ Emacs-24,3, chúng tôi khuyến cáo sử dụng cl-lib qua cl (được lên kế hoạch để loại bỏ trong một số tương lai xa), vì vậy nó sẽ là:

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

và kể từ Emacs-25, bạn cũng có thể sử dụng gói seq cho rằng:

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

này tốt hơn nên có một bình luận cho Gareth Rees' câu trả lời hơn là một câu trả lời riêng biệt trong nó quyền sở hữu. – Thomas

+0

@Thomas Không thể viết nhận xét nhiều dòng với các ví dụ về SO. – ceving

5

Common Lisp library cung cấp nhiều sequence functions như lập bản đồ, fil tering, gấp, tìm kiếm và thậm chí phân loại. Thư viện CL được vận chuyển với Emacs theo mặc định, vì vậy bạn nên dính vào nó. Tuy nhiên tôi thực sự thích thư viện dash.el, bởi vì nó cung cấp một lượng lớn các hàm cho các thao tác danh sách và cây. Nó cũng hỗ trợ anaphoric macros và khuyến khích lập trình hàm, làm cho mã ngắn gọn và thanh lịch.

nếp gấp của Haskell tương ứng với dash.el nếp gấp:

Sum của một loạt 1-10 sử dụng nếp gấp có thể trông giống như trong này trong Haskell và dash.el:

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

Bạn có thể biết, rằng nếp gấp là rất chung chung, và nó có thể thực hiện bản đồ và các bộ lọc thông qua nếp gấp . Ví dụ, để tăng mọi phần tử của 2, currying và phần Haskell sẽ cho phép cho mã ngắn gọn, nhưng trong elisp bạn thường sẽ viết lambdas verbose throwaway như thế:

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

Đoán những gì, nó không phải là cần thiết trong dash.el với các macro ẩn danh, cho phép cú pháp đặc biệt bằng cách hiển thị các biến của lambda dưới dạng các phím tắt, như itacc trong các nếp gấp. chức năng Anaphoric bắt đầu với 2 dấu gạch ngang thay vì 1:

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

Có rất nhiều lần giống như chức năng trong 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) 
Các vấn đề liên quan