Emacs Lisp:如何避免插入重复的列表项?

时间:2009-05-22 06:25:58

标签: emacs elisp

如何检查字符串是否已存在于Emacs Lisp的列表中?我需要检查某个路径字符串是否已经在exec-path中,然后将其添加到该列表中(如果不是)。谢谢!

2 个答案:

答案 0 :(得分:20)

添加列表功能将在添加

之前自动检查
(setq a '(1 2 3))
(add-to-list 'a 4)
(add-to-list 'a 3)

将导致a等于(4 1 2 3)

来自C-h f add-to-list:

add-to-list is a compiled Lisp function in `subr.el'.
(add-to-list list-var element &optional append compare-fn)

Add element to the value of list-var if it isn't there yet.
The test for presence of element is done with `equal',
or with compare-fn if that's non-nil.
If element is added, it is added at the beginning of the list,
unless the optional argument append is non-nil, in which case
element is added at the end.

The return value is the new value of list-var.

If you want to use `add-to-list' on a variable that is not defined
until a certain package is loaded, you should put the call to `add-to-list'
into a hook function that will be run only after loading the package.
`eval-after-load' provides one way to do this.  In some cases
other hooks, such as major mode hooks, can do the job.

答案 1 :(得分:2)

除了cobbal'sanswer add-to-list,还有cl-pushnew

(require 'cl-lib)

(setq list-of-strings '("one" "two" "three"))
(cl-pushnew "two" list-of-strings :test #'string=)
    ⇒ ("one" "two" "three")
(cl-pushnew "zero" list-of-strings :test #'string=)
    ⇒ ("zero" "one" "two" "three")

您需要使用:test #'string=参数,因为cl-pushnew默认使用eql进行比较,并且不会处理内容相同的两个字符串同样。 (equal)也可以。

(eql "some-string" "some-string")
    ⇒ nil
(string= "some-string" "some-string")
    ⇒ t
(equal "some-string" "some-string")
    ⇒ t

来自Emacs 26 C-h f cl-pushnew

cl-pushnew is a Lisp macro in ‘cl-lib.el’.

(cl-pushnew X PLACE [KEYWORD VALUE]...)

(cl-pushnew X PLACE): insert X at the head of the list if not already there.
Like (push X PLACE), except that the list is unmodified if X is ‘eql’ to
an element already on the list.

Keywords supported:  :test :test-not :key
相关问题