Elisp - 循环在alist上

时间:2011-12-14 21:00:55

标签: emacs elisp

在Emacs Lisp中循环使用alist并对每一对执行某些操作的最佳方法是什么?我想一个宏不会很困难,我只是想知道这是否是在某个地方构建的。有比下面更优雅的方式吗?

(setq my-list '((a . 1)
                (b . 2)
                (c . 3)))

(loop for key in (mapcar 'car my-list)
      for value in (mapcar 'cdr my-list)
      collect (cons value key))

;; Returns this
((1 . a)
 (2 . b)
 (3 . c))

4 个答案:

答案 0 :(得分:24)

来自 cl-macs.el

循环支持破坏CL:

(loop for (key . value) in my-list
      collect (cons value key))

答案 1 :(得分:15)

目前尚不清楚你究竟想做什么 - 问题非常笼统。有很多方法可以循环使用alist并对其部分或全部条目进行操作。你自己展示一种方式。另请参阅while,尤其是dolist。这是使用dolist的示例:

    (let ((res  ()))
     (dolist (x my-list)
       (push (cons (cdr x) (car x)) res))
     (nreverse res))

(使用loop的方法可能比您的示例更好 - 例如,无需构建三个列表(两个mapcar s + loop)。)< / p>

答案 2 :(得分:14)

在没有loop的情况下执行此操作的另一种方法是使用mapcar和lambda。我不认为它更优雅,但对于elisp而言,它与Common Lisp相比更为惯用:

(mapcar (lambda (element)
      (let ((key (car element))
            (value (cdr element)))
      (cons value key)))
      '((1 . a) (2 . b)))

答案 3 :(得分:7)

dash.el提供了许多列表操作功能,例如maps。那些接受函数作为参数的人也有anaphoric个对应物。这允许简洁的functional代码。 dash.el函数以破折号开头,因此名称和照应版本以2破折号开头。所以ataylor's variant看起来会更好:

(--map (cons (cdr it) (car it)) '((1 . a) (2 . b))) ; ((a . 1) (b . 2))