Elisp:如何查找列表重复项

时间:2018-02-27 09:46:01

标签: list duplicates lisp elisp

我用它来查找列表重复:

(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的开销,可能有更好的方法。

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:2)

这是您答案的简短版本,它使用std::exception而不是try { // throw exception here } catch (const std::exception &e) { // handle exception here } ,以避免后者的破坏性:

.my-upper-class{ .hidden-md, .hidden-sm, .hidden-lg}

我发现这相当容易阅读,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-duplicates的元素,这些元素具有重复项,并且返回delete-dups中每个 duplicated 元素的 position (记住cl--delete-duplicates在elisp中为零索引)。请注意,这目前仅适用于LIST的元素为LIST的情况,尽管我确信可以将其扩展到更一般的情况:

seq

例如

LIST
相关问题