[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 5269842833 2/3: Add a faster seq-uniq for lists
From: |
Lars Ingebrigtsen |
Subject: |
master 5269842833 2/3: Add a faster seq-uniq for lists |
Date: |
Tue, 9 Aug 2022 13:21:43 -0400 (EDT) |
branch: master
commit 5269842833471c960352ced3c60ce2329660b8cf
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>
Add a faster seq-uniq for lists
* lisp/emacs-lisp/seq.el (seq-uniq): Add a faster method for lists
(bug#57079).
---
lisp/emacs-lisp/seq.el | 17 +++++++++++++++++
test/lisp/emacs-lisp/seq-tests.el | 13 +++++++++++++
2 files changed, 30 insertions(+)
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 1b8d86563a..6ddd8de6e8 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -455,6 +455,23 @@ TESTFN is used to compare elements, or `equal' if TESTFN
is nil."
(setq result (cons elt result))))
(nreverse result)))
+(cl-defmethod seq-uniq ((sequence list) &optional testfn)
+ (let ((result nil))
+ (if (not testfn)
+ ;; Fast path.
+ (while sequence
+ (unless (member (car sequence) result)
+ (push (car sequence) result))
+ (pop sequence))
+ ;; Slower path.
+ (while sequence
+ (unless (seq-find (lambda (elem)
+ (funcall testfn elem (car sequence)))
+ result)
+ (push (car sequence) result))
+ (pop sequence)))
+ (nreverse result)))
+
(cl-defgeneric seq-mapcat (function sequence &optional type)
"Concatenate the result of applying FUNCTION to each element of SEQUENCE.
The result is a sequence of type TYPE, or a list if TYPE is nil."
diff --git a/test/lisp/emacs-lisp/seq-tests.el
b/test/lisp/emacs-lisp/seq-tests.el
index 3b22e42df2..a655377e6c 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -559,5 +559,18 @@ Evaluate BODY for each created sequence.
(should (equal (seq-split seq 3)
'("012" "345" "678" "9")))))
+(ert-deftest test-seq-uniq-list ()
+ (let ((list '(1 2 3)))
+ (should (equal (seq-uniq (append list list)) '(1 2 3))))
+ (let ((list '(1 2 3 2 1)))
+ (should (equal (seq-uniq list) '(1 2 3))))
+ (let ((list (list (substring "1")
+ (substring "2")
+ (substring "3")
+ (substring "2")
+ (substring "1"))))
+ (should (equal (seq-uniq list) '("1" "2" "3")))
+ (should (equal (seq-uniq list #'eq) '("1" "2" "3" "2" "1")))))
+
(provide 'seq-tests)
;;; seq-tests.el ends here