如何在Emacs lisp中将多个元素添加到列表中

17

在Emacs Lisp中,有一个add-to-list函数可以将单个元素添加到列表中(如果该元素不存在)。

与其添加一个元素,我想要添加多个元素。另外,我不想过滤掉重复的元素,而是仍然将它们添加到列表中。

目前,我已经实现了以下函数:

(defun append-to-list (list-var elements)
  "Append ELEMENTS to the end of LIST-VAR.

The return value is the new value of LIST-VAR."
  (set list-var (append (symbol-value list-var) elements)))

这个函数做了我想要的事情,但我想知道在Emacs lisp中是否已经有类似的(或更好的)东西存在。我不想重复造轮子。

更新1: Stefan指出下面的代码无法使用词法作用域。有没有办法让它正常工作?

更新2:之前我认为重复过滤是可以的,但实际上不行。我确实需要重复项。


1
你的代码很好。没有类似的系统函数。 - sds
1
我不会说它很“好”,但是它可以工作。使用symbol-valueset意味着它不能与词法作用域变量一起使用。除非你真的需要它,最好在开头添加elements,因为elements几乎总是比list-var短(有时甚至短得多)。 - Stefan
有没有办法让代码使用词法作用域工作? - Viktor Rosenfeld
5个回答

11

这几乎相当于1,但更快,因为它在追加新元素之前不会复制原始列表。

(defun append-to-list (list-var elements)
  "Append ELEMENTS to the end of LIST-VAR.

The return value is the new value of LIST-VAR."
  (unless (consp elements)
    (error "ELEMENTS must be a list"))
  (let ((list (symbol-value list-var)))
    (if list
        (setcdr (last list) elements)
      (set list-var elements)))
  (symbol-value list-var))

1 append 不会复制最后一个元素,而是直接将其作为新列表的尾部使用,因此这部分是相同的。但是,如果原始列表对象(或某个部分)有其他引用,则通过 append 复制该列表和仅扩展它(使用 setcdr)之间会存在功能差异。当然,您实际想要哪种结果取决于您。


如果原始列表为空,则会出现错误! - Stefan
糟糕,已修复。感谢Stefan。 - phils
至少在我的当前用例中,我不会保留引用。因此,这对我来说看起来更清晰,因为它避免了复制。谢谢!但是它能够使用词法作用域吗? - Viktor Rosenfeld
不,当“list-var”参数是符号时,您无法使用词法作用域来完成此操作,因为这样做已经失去了对词法值的访问权限。您必须传递列表并直接操作它。 - phils

8

我在我的初始化文件中有以下代码,它允许添加多个元素。虽然这种循环添加的方式可以避免重复元素,但不知道其效率如何。

(defun jlp/add-to-list-multiple (list to-add)
  "Adds multiple items to LIST.
Allows for adding a sequence of items to the same list, rather
than having to call `add-to-list' multiple times."
  (interactive)
  (dolist (item to-add)
    (add-to-list list item)))

这不行,因为我实际上需要列表中的重复值。 - Viktor Rosenfeld
如果您需要重复项,可以使用 push 而不是 add-to-list - Matt Kramer

3
如果您不关心顺序:
(setf var (cl-list* elt1 elt2 elt3 var))
< p > list* 的最后一个参数成为结果列表的尾部。


2

如果你想过滤重复元素,你还可以使用dash.el

(setq list1 (-union list1 list2))

1

有时我会这样做:

(setq l `(,@l i1 i2 i3))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接