簡體   English   中英

Elisp:如何查找列表重復項

[英]Elisp: how to find list duplicates

我用它來查找列表重復:

(defun have-dups (x)
  (let ((dups (copy-tree x)))
    (if (eq (length (delete-dups dups)) (length x))
    nil
      t)))

(have-dups (list 1 2 3 3)) ;=> t
(have-dups (list 1 2 3))   ;=> nil 

考慮到copy-treedelete-dups ,可能有更好的方法。

使用哈希表,只要找到哈希表中已存在的元素,就知道你有重復項:

(defun has-dup (list)
  (block nil
    (let ((hash (make-hash-table :test 'eql)))
      (map ()
           (lambda (item)
             (if (gethash item hash)
                 (return t)
               (setf (gethash item hash) t)))
           list))))

這是您的答案的較短版本,它使用remove-duplicates而不是delete-dups來避免后者的破壞性屬性:

(defun has-dups-p (LIST) ""
       (let ((unique1 (remove-duplicates LIST :test #'equal)))
     (if (eq LIST unique1)
         nil
       t)))
(has-dups '(1 2 3 2 1)) ; t
(has-dups '("a" "b" "c")) ; nil

我發現這個相當容易閱讀,並且eq應該是合理有效的,因為它直接到C ,特別是在列表的早期發生重復的情況下。 remove-duplicatesdelete-dups都被傳遞給cl--delete-duplicates ,這是相當delete-dups ......

較長的溶液如下,它返回的元素LIST具有重復,並且每個復制的元件在位置 LIST (記住seq s為在elisp的零索引)。 請注意,這當前僅適用於LIST的元素是string s的情況,盡管我確信它可以進一步擴展到更一般的情況:

(defun list-duplicates (LIST) "
Returns `nil' when LIST has no duplicates.
Otherise, returns a `list' of `cons's.
In each list element:
- the `car' is the element of LIST which has duplicates.
- the `cdr' is a list of the positions where the duplicates are found."
   (interactive)
   ;; res1 = result
   ;; unique1 = LIST with duplicates removed
   (let ((unique1 (remove-duplicates LIST :test #'string-equal))
     (res1 '()))
     (if (eq LIST unique1)
     nil
       (progn
     (dolist (x unique1)
       ;; i = incrementor
       ;; pos1 = list of postions of duplicates
       (let (y (i 0) (pos1 '()))
         (while (member x LIST)
           (set 'y (seq-position LIST x))
           (when (> i 0)
         (push y pos1))
           (set 'i (+ 1 i))
           (set 'LIST
            (substitute (concat x "1") x LIST :test #'string-equal :count 1)))
         (push (cons x (nreverse pos1)) res1)))
     (nreverse res1)))))

例如

(list-duplicates '("a" "b" "c")) ; nil
(list-duplicates '("a" "b" "b" "a" "b" "c" "c")) ; (("a" 3) ("b" 2 4) ("c" 6))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM