2010-11-22 49 views

回答

25

如果

(require 'cl) 

,那麼你可以使用Common Lisp的功能reduce。通過foldr的關鍵字參數:from-end t

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

因爲emacs-24.3,我們建議在cl使用cl-lib(這是計劃在一些遙遠的未來去除),所以這將是:

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

以來的Emacs-25,你也可以使用包seq爲:

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

這應該更好的是加雷思·雷斯的回答不是在一個單獨的答案評論其自己的權利。 – Thomas 2014-02-07 13:06:12

+0

@Thomas不可能用SO上的例子編寫多行註釋。 – ceving 2018-02-02 08:04:53

5

Common Lisp library提供了大量的等sequence functions映射,FIL尋找,摺疊,搜索甚至排序。 CL庫在默認情況下與Emacs一起發貨,所以您應該堅持使用它。不過我真的很喜歡dash.el庫,因爲它爲列表和樹的操作提供了大量的函數。它還支持anaphoric macros並鼓勵函數式編程,這使得代碼簡潔而優雅。

Haskell的褶皺對應與dash.el摺疊:

總和範圍爲1至10採用褶皺看起來就像這個在Haskell和dash.el

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

你可能知道,褶皺都非常一般,而且有可能實現通過摺疊地圖和過濾器。例如,要加2的每一個元素,Haskell的鑽營和路段將允許簡潔的代碼,但在elisp的你通常會編寫冗長的一次性lambda表達式這樣的:

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

猜猜看,這是沒有必要dash.el與指示宏,它允許特殊的語法通過暴露lambda的變量作爲快捷方式,如摺疊itacc。在dash.el

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

有褶皺狀的很多功能:照應功能開始2個破折號,而不是1

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