【问题标题】:Elisp - Loop over an alistElisp - 遍历一个列表
【发布时间】:2011-12-14 21:00:54
【问题描述】:

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

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:
    来自 cl-macs.el

    cl-loop 支持像 CL 一样进行破坏:

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

    【讨论】:

    • 现在 cl 已被弃用,现代等效于使用来自 cl-lib 的功能相同的 cl-loop 宏。该库内置于较新的 emacs 版本中,并且可以从 GNU ELPA 获得向后兼容的包。
    • 这里的“收集”是什么意思?
    【解决方案2】:

    不使用loop 的另一种方法是使用mapcar 和一个lambda。我不认为它更优雅,但与 Common Lisp 相比,它更适合 elisp:

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

    【讨论】:

    • 我更喜欢这个答案,因为它不使用cl
    • @kindahero 你知道循环是一个 cl 宏吧?完全没问题。
    • 但是请注意,字节编译会警告使用 mapcar 的副作用,即。在顶层,它的返回值被忽略。对于简单的迭代,dolist 是首选。
    • @sanityinc 这应该在答案中。
    【解决方案3】:

    不清楚您到底想做什么——这个问题很笼统。有很多方法可以遍历 alist 并对其部分或全部条目进行操作。你自己展示一种方式。还请查看while,尤其是dolist。这是您使用dolist 的示例:

    (让 ((res ()))) (dolist (x my-list) (推(缺点(cdr x)(汽车 x))res)) (nreverse res))

    (与您的示例相比,使用loop 可能有更好的方法——无需构建三个列表(例如,两个mapcars + loop)。)

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-16
        • 2021-10-30
        • 1970-01-01
        • 1970-01-01
        • 2022-06-18
        • 2017-04-09
        • 2011-03-18
        相关资源
        最近更新 更多