1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 10:30:25 -08:00

Add new function `seq-positions'

* doc/lispref/sequences.texi (Sequence Functions): Document it.

* lisp/emacs-lisp/seq.el (seq-positions): New function.

* lisp/emacs-lisp/shortdoc.el (sequence): Mention it.

* test/lisp/emacs-lisp/seq-tests.el (test-seq-positions): Test it
(bug#57548).
This commit is contained in:
Damien Cassou 2022-09-04 13:21:59 +02:00 committed by Lars Ingebrigtsen
parent 4d50d413e6
commit 4751b51d5e
5 changed files with 54 additions and 0 deletions

View file

@ -898,6 +898,27 @@ use instead of the default @code{equal}.
@end example
@end defun
@defun seq-positions sequence elt &optional testfn
This function returns a list of the (zero-based) indices of the
elements in @var{sequence} for which @var{testfn} returns
non-@code{nil} when passed the element and @var{elt} as
arguments. @var{testfn} defaults to @code{equal}.
@example
@group
(seq-positions '(a b c a d) 'a)
@result{} (0 3)
@end group
@group
(seq-positions '(a b c a d) 'z)
@result{} nil
@end group
@group
(seq-positions '(11 5 7 12 9 15) 10 #'>=)
@result{} (0 3 5)
@end group
@end example
@end defun
@defun seq-uniq sequence &optional function
This function returns a list of the elements of @var{sequence} with

View file

@ -2742,6 +2742,11 @@ compiler now emits a warning about this deprecated usage.
These can be used for buttons in buffers and the like. See the
"(elisp) Icons" and "(emacs) Icons" nodes in the manuals for details.
+++
** New function 'seq-positions'.
This returns a list of the (zero-based) indices of elements matching a
given predicate in the specified sequence.
+++
** New arguments MESSAGE and TIMEOUT of 'set-transient-map'.
MESSAGE specifies a message to display after activating the transient

View file

@ -459,6 +459,23 @@ Equality is defined by the function TESTFN, which defaults to `equal'."
(setq index (1+ index)))
nil)))
;;;###autoload
(cl-defgeneric seq-positions (sequence elt &optional testfn)
"Return indices for which (TESTFN (seq-elt SEQUENCE index) ELT) is non-nil.
TESTFN is a two-argument function which is passed each element of
SEQUENCE as first argument and ELT as second. TESTFN defaults to
`equal'.
The result is a list of (zero-based) indices."
(let ((result '()))
(seq-do-indexed
(lambda (e index)
(when (funcall (or testfn #'equal) e elt)
(push index result)))
sequence)
(nreverse result)))
;;;###autoload
(cl-defgeneric seq-uniq (sequence &optional testfn)
"Return a list of the elements of SEQUENCE with duplicates removed.

View file

@ -846,6 +846,10 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'),
:eval (seq-find #'numberp '(a b 3 4 f 6)))
(seq-position
:eval (seq-position '(a b c) 'c))
(seq-positions
:eval (seq-positions '(a b c a d) 'a)
:eval (seq-positions '(a b c a d) 'z)
:eval (seq-positions '(11 5 7 12 9 15) 10 #'>=))
(seq-length
:eval (seq-length "abcde"))
(seq-max

View file

@ -490,6 +490,13 @@ Evaluate BODY for each created sequence.
(should (= (seq-position seq 'a #'eq) 0))
(should (null (seq-position seq (make-symbol "a") #'eq)))))
(ert-deftest test-seq-positions ()
(with-test-sequences (seq '(1 2 3 1 4))
(should (equal '(0 3) (seq-positions seq 1)))
(should (seq-empty-p (seq-positions seq 9))))
(with-test-sequences (seq '(11 5 7 12 9 15))
(should (equal '(0 3 5) (seq-positions seq 10 #'>=)))))
(ert-deftest test-seq-sort-by ()
(let ((seq ["x" "xx" "xxx"]))
(should (equal (seq-sort-by #'seq-length #'> seq)