diff options
Diffstat (limited to 'lisp/emacs-lisp/seq.el')
-rw-r--r-- | lisp/emacs-lisp/seq.el | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 025d94e10b9..c5f5906e7e5 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -4,7 +4,8 @@ ;; Author: Nicolas Petton <nicolas@petton.fr> ;; Keywords: sequences -;; Version: 1.1 +;; Version: 1.3 +;; Package: seq ;; Maintainer: emacs-devel@gnu.org @@ -32,8 +33,8 @@ ;; ;; All provided functions work on lists, strings and vectors. ;; -;; Functions taking a predicate or a function iterating over the -;; sequence as argument take the function as their first argument and +;; Functions taking a predicate or iterating over a sequence using a +;; function as argument take the function as their first argument and ;; the sequence as their second argument. All other functions take ;; the sequence as their first argument. ;; @@ -171,9 +172,7 @@ The result is a sequence of the same type as SEQ." (if (listp seq) (sort (seq-copy seq) pred) (let ((result (seq-sort pred (append seq nil)))) - (cond ((stringp seq) (concat result)) - ((vectorp seq) (vconcat result)) - (t (error "Unsupported sequence: %s" seq)))))) + (seq-into result (type-of seq))))) (defun seq-contains-p (seq elt &optional testfn) "Return the first element in SEQ that equals to ELT. @@ -245,17 +244,38 @@ negative integer or 0, nil is returned." "Apply FUNCTION to each element of SEQ. Separate the elements of SEQ into an alist using the results as keys. Keys are compared using `equal'." - (nreverse - (seq-reduce - (lambda (acc elt) - (let* ((key (funcall function elt)) - (cell (assoc key acc))) - (if cell - (setcdr cell (push elt (cdr cell))) - (push (list key elt) acc)) - acc)) - seq - nil))) + (seq-reduce + (lambda (acc elt) + (let* ((key (funcall function elt)) + (cell (assoc key acc))) + (if cell + (setcdr cell (push elt (cdr cell))) + (push (list key elt) acc)) + acc)) + (seq-reverse seq) + nil)) + +(defalias 'seq-reverse + (if (ignore-errors (reverse [1 2])) + #'reverse + (lambda (seq) + "Return the reversed copy of list, vector, or string SEQ. +See also the function `nreverse', which is used more often." + (let ((result '())) + (seq-map (lambda (elt) (push elt result)) + seq) + (if (listp seq) + result + (seq-into result (type-of seq))))))) + +(defun seq-into (seq type) + "Convert the sequence SEQ into a sequence of type TYPE. +TYPE can be one of the following symbols: vector, string or list." + (pcase type + (`vector (vconcat seq)) + (`string (concat seq)) + (`list (append seq nil)) + (t (error "Not a sequence type name: %s" type)))) (defun seq--drop-list (list n) "Return a list from LIST without its first N elements. @@ -300,7 +320,6 @@ This is an optimization for lists in `seq-take-while'." (defalias 'seq-copy #'copy-sequence) (defalias 'seq-elt #'elt) -(defalias 'seq-reverse #'reverse) (defalias 'seq-length #'length) (defalias 'seq-do #'mapc) (defalias 'seq-each #'seq-do) |