From 5269842833471c960352ced3c60ce2329660b8cf Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 9 Aug 2022 19:18:55 +0200 Subject: [PATCH] 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 1b8d86563a1..6ddd8de6e8d 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 3b22e42df24..a655377e6cc 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 -- 2.39.2