Listeye nasıl eleman numarası eklenir?


16

S: Öğe numarasını bir listeye nasıl alabilirim?

nthn numaralı öğeyi listeden alır:

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

Ben tersini yapmak istiyorum: eleman verilen eleman numarasını almak:

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

Kaçırmış olabilirim, ama böyle bir işlev var mı? Bunu nasıl yaparsınız?

Yanıtlar:


22
  1. İşte Emacs 24.3 ve sonraki sürümlerinde bulunan bir işlev:
(cl-position 2 '(6 7 8 2 3 4)) ;; => 3

(Emacs 24.3'ten önce, Emacs ile birlikte positiongelen kitaplık işlevini kullanın cl.el.)

:testKarşılaştırma işlevini belirtmek için anahtar kelimeyi kullanabilirsiniz :

(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 Emülasyon Kılavuzu

  1. dash.el bunu yapabilen bir işlevi vardır: -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

Bu Emacs ile birlikte, ancak Emacs çok sayıda kullanıcı zaten yüklü değil (o bir bağımlılık var projectile, flycheckve smartparenso kapsama bir ton veren).


6

Kullanmak yerine kendi başınızı döndürmek cl-positionistiyorsanız ve iki kez (kullanarak length) geçmek istemiyorsanız ...

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

Eski Emacs sürümleri için bile iyi. Ancak, isteyebileceğiniz veya istemediğiniz bu davranış farkı vardır: Noktalı listenin arabaları için de çalışır. Yani, sexps gibi bir hata oluşturmak yerine pozisyonu doğru bir şekilde döndürür (nth-elt 'c '(a b c . d)).

Yanlış bir liste için her zaman bir hata oluşturmak istiyorsanız, o zaman listenin sonuna gitmeyi gerektiren bu durumu kontrol etmek istersiniz:

(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

Bu kadar etkili olmasa da, yazmanın basit bir işlevi olduğu ortaya çıkıyor:

(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

Varsa, yerleşik bir çözümü tercih ederim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.