Elisp - 循环在alist上

Joe*_*Joe 20 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))
Run Code Online (Sandbox Code Playgroud)

Jür*_*zel 26

来自cl-macs.el的循环支持像CL这样的破坏:

(loop for (key . value) in my-list
      collect (cons value key))
Run Code Online (Sandbox Code Playgroud)

  • 现在不推荐使用`cl`,现代的等价是使用`cl-lib`中功能相同的`cl-loop`宏.该库内置于较新的emacs版本中,GNU ELPA提供了向后兼容的软件包. (5认同)
  • 这里的“收集”是什么意思? (2认同)

Dre*_*rew 15

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

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

(可能有一种loop比你的例子更好的使用方法- 例如,不需要构建三个列表(两个mapcars + loop).)


ata*_*lor 14

另外一种方法loop是使用mapcar和lambda.我不认为它更优雅,但与Common Lisp相比,它更像是elisp的惯用语:

(mapcar (lambda (element)
      (let ((key (car element))
            (value (cdr element)))
      (cons value key)))
      '((1 . a) (2 . b)))
Run Code Online (Sandbox Code Playgroud)

  • 但请注意,字节编译警告使用mapcar进行副作用,即.在顶层,忽略其返回值.对于简单的迭代,"dolist"是首选. (7认同)

Mir*_*lov 7

dash.el提供许多列表操作功能,如地图.那些接受函数作为参数也有照应同行.这允许简洁的功能代码.dash.el函数以破折号开头,因此名称和照应版本以2个破折号开头.因此,ataylor的变体看起来会更好:

(--map (cons (cdr it) (car it)) '((1 . a) (2 . b))) ; ((a . 1) (b . 2))
Run Code Online (Sandbox Code Playgroud)