Common Lisp中了兩個列表的功能,我可以做到這一點:映射的elisp
(mapcar #'cons '(1 2 3) '(a b c))
=> ((1 . A) (2 . B) (3 . C))
我該怎麼做同樣的事情在elisp的?當我嘗試,我得到一個錯誤:
(wrong-number-of-arguments mapcar 3)
如果elisp的的mapcar可以在一個名單上每次只工作,怎麼是兩個清單合併成一個ALIST的idomatic方式?
Common Lisp中了兩個列表的功能,我可以做到這一點:映射的elisp
(mapcar #'cons '(1 2 3) '(a b c))
=> ((1 . A) (2 . B) (3 . C))
我該怎麼做同樣的事情在elisp的?當我嘗試,我得到一個錯誤:
(wrong-number-of-arguments mapcar 3)
如果elisp的的mapcar可以在一個名單上每次只工作,怎麼是兩個清單合併成一個ALIST的idomatic方式?
你想mapcar*
,它接受一個或多個序列(不只是列出了在Common Lisp的),以及一個序列參數工作就像普通mapcar
。
(mapcar* #'cons '(1 2 3) '(a b c))
((1 . A) (2 . B) (3 . C))
即使沒有定義它,你可以很容易滾你自己:
(defun mapcar* (f &rest xs)
"MAPCAR for multiple sequences"
(if (not (memq nil xs))
(cons (apply f (mapcar 'car xs))
(apply 'mapcar* f (mapcar 'cdr xs)))))
Emacs中內置了Common Lisp library,它引入了大量的Common Lisp的函數和宏,但與前綴爲cl-
。沒有理由避免這個庫。 cl-mapcar
是你想要什麼:
(cl-mapcar '+ '(1 2 3) '(10 20 30)) ; (11 22 33)
隨着dash
列表操作庫(見installation instructions),你可以使用-zip-with
(記住:-zip-with
是cl-mapcar
同樣適用於2所列出):
(-zip-with '+ '(1 2 3) '(10 20 30)) ; (11 22 33)
我不知道爲3個參數實現等效的-zip-with
的優雅方式。但是,你可以使用-partial
從dash-functional
包,自帶dash
(功能從dash-functional
需要Emacs的24)。 -partial
部分應用功能,所以下面這兩個函數調用是等效的:
(-zip-with '+ '(1 2) '(10 20)) ; (11 22)
(funcall (-partial '-zip-with '+) '(1 2) '(10 20)) ; (11 22)
然後,你可以用它與-reduce
功能:
(-reduce (-partial '-zip-with '+) '((1 2 3) (10 20 30) (100 200 300)))
; (111 222 333)
您可以&rest
關鍵字把它包裝成一個函數,所以這個函數會接受不同數量的參數而不是一個列表:
(defun -map* (&rest lists)
(-reduce (-partial 'zip-with '+) lists))