如何获取列表中的元素编号?


16

问:如何获取列表中的元素编号?

nth从列表中获取元素编号n

(nth 2 '(a b c d))                      ; => c

我想相反:获取给定元素的元素编号:

(some-function 'c '(a b c d))           ; => 2

我可能已经错过了,但是是否存在这样的功能?一个人怎么做?

Answers:


22
  1. 这是Emacs 24.3和更高版本附带的功能:
(cl-position 2 '(6 7 8 2 3 4)) ;; => 3

(在Emacs 24.3之前,请使用Emacs附带的positionlibrary中的函数cl.el。)

您可以使用:test关键字来指定比较功能:

(cl-position "bar" '("foo" "bar" "baz") :test 'equal) ;; => 1
(cl-position '(1 2) '((3) (5 6) (1 2) nil) :test 'equal) ;; => 2

Emacs Common Lisp仿真手册

  1. dash.el 具有可以执行此操作的功能: -elem-index
(-elem-index 2 '(6 7 8 2 3 4)) ;; => 3
(-elem-index "bar" '("foo" "bar" "baz")) ;; => 1
(-elem-index '(1 2) '((3) (5 6) (1 2) nil)) ;; => 2

它没有包含在Emacs中,但是许多Emacs用户已经安装了它(它是,和的依赖项projectile,因此具有很多覆盖范围)。flychecksmartparens


6

好吧,如果您想自己滚动而不是使用cl-position,并且不想遍历两次(使用length)...

(defun nth-elt (element xs)
  "Return zero-indexed position of ELEMENT in list XS, or nil if absent."
  (let ((idx  0))
    (catch 'nth-elt
      (dolist (x  xs)
        (when (equal element x) (throw 'nth-elt idx))
        (setq idx  (1+ idx)))
      nil)))

这对于旧的Emacs版本也很好。但是,它具有这种行为上的差异,您可能希望也可能不想要:它也适用于虚线列表中的汽车。也就是说,对于诸如之类的性别,它会正确返回位置而不是引发错误(nth-elt 'c '(a b c . d))

如果您总是要为不正确的列表引发错误,则需要检查这种情况,这需要始终遍历列表的末尾:

(defun nth-elt (element xs)
  "Return zero-indexed position of ELEMENT in list XS, or nil if absent."
  (let ((idx  0))
    (when (atom (cdr (last xs))) (error "Not a proper list"))
    (catch 'nth-elt
      (dolist (x  xs)
        (when (equal element x) (throw 'nth-elt idx))
        (setq idx  (1+ idx)))
      nil)))

2

事实证明,这是一个简单的编写函数,尽管可能效率不高:

(defun nth-elt (elt list)
  "Return element number of ELT in LIST."
  (let ((loc (length (member elt list))))
    (unless (zerop loc)
      (- (length list) loc))))

(nth-elt 'c '(a b c d))                 ; => 2
(nth-elt 'f '(a b c d))                 ; => nil

当然,如果有内置解决方案,我会更喜欢。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.