จะรับหมายเลของค์ประกอบในรายการได้อย่างไร


16

ถาม:ฉันจะรับหมายเลของค์ประกอบในรายการได้อย่างไร

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 ให้ใช้ฟังก์ชั่นpositionจากไลบรารีcl.elซึ่งมาพร้อมกับ Emacs)

คุณสามารถใช้:testคำสำคัญเพื่อระบุฟังก์ชั่นการเปรียบเทียบ:

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

คู่มือการเลียนแบบเสียงกระเพื่อม Emacs ทั่วไป

  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, flycheckและsmartparensซึ่งจะทำให้มันตันของความคุ้มครอง)


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 รุ่นเก่า ๆ อย่างไรก็ตามมันมีความแตกต่างของพฤติกรรมนี้ซึ่งคุณอาจต้องการหรือไม่ต้องการ: มันใช้ได้กับรถยนต์ของรายการที่มีจุดด้วย นั่นคือมันอย่างถูกต้องจะส่งกลับตำแหน่งแทนของการเพิ่มข้อผิดพลาดสำหรับ 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.