Làm thế nào để có được số phần tử trong một danh sách?


16

Q: làm thế nào để tôi có được số phần tử trong danh sách?

nthlấy số phần tử n từ danh sách:

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

Tôi muốn làm ngược lại: lấy số phần tử cho phần tử:

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

Tôi có thể đã bỏ lỡ nó, nhưng một chức năng như vậy có tồn tại? Làm thế nào một người sẽ làm điều này?

Câu trả lời:


22
  1. Đây là một chức năng được bao gồm trong Emacs 24.3 trở lên:
(cl-position 2 '(6 7 8 2 3 4)) ;; => 3

(Trước Emacs 24.3, hãy sử dụng chức năng positiontừ thư viện cl.el, được bao gồm trong Emacs.)

Bạn có thể sử dụng :testtừ khóa để chỉ định chức năng so sánh:

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

Hướng dẫn thi đua Lisp chung của Emacs

  1. dash.el có một chức năng có thể làm điều này: -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

Nó không bao gồm trong Emacs, nhưng rất nhiều người dùng Emacs đã có nó được cài đặt (đó là một sự phụ thuộc của projectile, flychecksmartparens, trong đó cung cấp cho nó một tấn bảo hiểm).


6

Chà, nếu bạn muốn tự lăn thay vì sử dụng cl-positionvà bạn không muốn đi qua hai lần (sử dụng 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)))

Điều đó tốt cho cả các phiên bản Emacs cũ. Tuy nhiên, nó có sự khác biệt về hành vi này, điều mà bạn có thể muốn hoặc không muốn: Nó cũng hoạt động đối với những chiếc xe trong danh sách chấm. Đó là, nó trả lại chính xác vị trí thay vì đưa ra một lỗi, đối với giới tính như (nth-elt 'c '(a b c . d)).

Nếu bạn muốn luôn đưa ra một lỗi cho danh sách không phù hợp, thì bạn sẽ muốn kiểm tra trường hợp đó, yêu cầu luôn luôn đi qua cuối danh sách:

(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

Hóa ra đó là một chức năng đơn giản để viết, mặc dù nó có thể không hiệu quả lắm:

(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

Tất nhiên, tôi thích một giải pháp tích hợp hơn nếu có.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.