リスト内の要素番号を取得する方法は?


16

Q:リストで要素番号を取得するにはどうすればよいですか?

nthリストから要素番号nを取得します。

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

私は逆にしたい:要素を指定して要素番号を取得する:

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

見逃したかもしれませんが、そのような機能はありますか?これをどのように行うのでしょうか?

回答:


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のユーザーの多くは、すでにそれがインストールされています(それはの依存関係だprojectileflychecksmartparensそれを報道のトンを与えます、)。


6

さて、を使用する代わりに独自のロールcl-positionを行いたい場合、および(を使用してlength)2回トラバースしたくない場合...

(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バージョンでも有効です。ただし、この動作の違いがあり、必要な場合とそうでない場合があります。点線リストの車に対しても機能します。つまり、などのsexpsに対して、エラーを発生させる代わりに正しく位置を返します(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

もちろん、組み込みのソリューションが存在する場合はそれを好むでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.