我想找到elisp的类比:
sum(n for n in numbers if n % 2) # Python
numbers.select { |n| n % 2 != 0 }.inject { |a, b| a + b } # Ruby
Run Code Online (Sandbox Code Playgroud)
势在必行:
(defun oddp (number)
(not (= (mod number 2) 0)))
(defun sum-odd-with-dolist (list)
(let ((acc 0))
(dolist (item list acc)
(if (oddp item)
(setq acc (+ item acc))))))
Run Code Online (Sandbox Code Playgroud)
(defun sum-odd-with-dolist-incr (list)
(let ((total 0))
(dolist (item list)
(if (oddp item)
(incf total item)))
total))
Run Code Online (Sandbox Code Playgroud)
使用' cl-*' loop:
(defun sum-odd-with-loop (list)
(loop for x in list if (oddp x) sum x))
(sum-odd-with-loop '(1 2 3))
4
Run Code Online (Sandbox Code Playgroud)
是否有更惯用的方法(不需要cl-*包)?
Gar*_*ees 14
惯用的方法是使用包中的函数和宏cl.它们是Emacs Lisp的标准配置,使用它们没有任何问题.
我怀疑你会找到一种简洁明了的方法
(loop for x in list if (oddp x) sum x)
Run Code Online (Sandbox Code Playgroud)
有更多功能性的方法,例如
(apply #'+ (remove-if-not #'oddp list))
Run Code Online (Sandbox Code Playgroud)
但这种使用remove-if-not是从cl-seq包.你可以手写出一个循环:
(let ((sum 0)) (dolist (x list sum) (when (oddp x) (incf sum x))))
Run Code Online (Sandbox Code Playgroud)
但是这个使用dolist,incf哪些都在cl-macs包中.基本上你无法逃避cl包裹:oddp本身就是一个cl功能!
我绝对没有cl设施的最大努力是这样的:
(apply #'+ (mapcar (lambda (x) (* x (mod x 2))) list))
Run Code Online (Sandbox Code Playgroud)
但在实践中使用它而不是(loop ...)版本是荒谬的.
(apply '+ (delq nil (mapcar (lambda (x) (and (= 1 (% x 2)) x)) '(1 2 3 4 5))))
Run Code Online (Sandbox Code Playgroud)