unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#57548: Add new function `seq-positions'
@ 2022-09-02 18:43 Damien Cassou
  2022-09-02 19:00 ` Eli Zaretskii
  2022-09-03  1:42 ` Michael Heerdegen
  0 siblings, 2 replies; 12+ messages in thread
From: Damien Cassou @ 2022-09-02 18:43 UTC (permalink / raw)
  To: 57548

[-- Attachment #1: Type: text/plain, Size: 192 bytes --]

Tags: patch

Hi,

here is a patch adding seq-positions to seq.el.

-- 
Damien Cassou

"Success is the ability to go from one failure to another without
losing enthusiasm." --Winston Churchill

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-new-function-seq-positions.patch --]
[-- Type: text/patch, Size: 4041 bytes --]

From cdb5806faa1ce7c5a6c4bd11ff489e392d6e7fe6 Mon Sep 17 00:00:00 2001
From: Damien Cassou <damien@cassou.me>
Date: Fri, 2 Sep 2022 14:54:36 +0200
Subject: [PATCH] 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.
---
 doc/lispref/sequences.texi        | 17 +++++++++++++++++
 etc/NEWS                          |  5 +++++
 lisp/emacs-lisp/seq.el            | 12 ++++++++++++
 lisp/emacs-lisp/shortdoc.el       |  3 +++
 test/lisp/emacs-lisp/seq-tests.el |  5 +++++
 5 files changed, 42 insertions(+)

diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 1f6f80521c..dc13180a11 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -880,6 +880,23 @@ Sequence Functions
 @end example
 @end defun
 
+@defun seq-positions sequence elt &optional testfn
+  This function returns a list of the positions of the elements in
+@var{sequence} that are equal to @var{elt}.  If the optional argument
+@var{testfn} is non-@code{nil}, it is a function of two arguments to
+use instead of the default @code{equal}.
+
+@example
+@group
+(seq-positions '(a b c a d) 'a)
+@result{} (0 3)
+@end group
+@group
+(seq-position '(a b c a d) 'z)
+@result{} nil
+@end group
+@end example
+@end defun
 
 @defun seq-uniq sequence &optional function
   This function returns a list of the elements of @var{sequence} with
diff --git a/etc/NEWS b/etc/NEWS
index 1512d45fdc..0f09891914 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2710,6 +2710,11 @@ The default timeout value can be defined by the new variable
 ** New function 'seq-split'.
 This returns a list of sub-sequences of the specified sequence.
 
++++
+** New function 'seq-positions'.
+This returns a list of the positions of a given element in the
+specified sequence.
+
 +++
 ** 'plist-get', 'plist-put' and 'plist-member' are no longer limited to 'eq'.
 These function now take an optional comparison predicate argument.
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index b6f0f66e5b..7db7cd0cd6 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -445,6 +445,18 @@ seq-position
         (setq index (1+ index)))
       nil)))
 
+;;;###autoload
+(cl-defgeneric seq-positions (sequence elt &optional testfn)
+  "Return a list of the positions of ELT in SEQ.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (let ((result '())
+        (index 0))
+    (seq-doseq (e sequence)
+      (when (funcall (or testfn #'equal) e elt)
+        (push index result))
+      (setq index (1+ index)))
+    (nreverse result)))
+
 ;;;###autoload
 (cl-defgeneric seq-uniq (sequence &optional testfn)
   "Return a list of the elements of SEQUENCE with duplicates removed.
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index 990dabe351..80b9c0a69e 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -846,6 +846,9 @@ sequence
    :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))
   (seq-length
    :eval (seq-length "abcde"))
   (seq-max
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el
index 1a27467d29..7f06a7e618 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -482,6 +482,11 @@ test-seq-position
     (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)))))
+
 (ert-deftest test-seq-sort-by ()
   (let ((seq ["x" "xx" "xxx"]))
     (should (equal (seq-sort-by #'seq-length #'> seq)
-- 
2.36.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-09-06  1:44 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-02 18:43 bug#57548: Add new function `seq-positions' Damien Cassou
2022-09-02 19:00 ` Eli Zaretskii
2022-09-03  8:01   ` Damien Cassou
2022-09-03 10:16     ` Eli Zaretskii
2022-09-03 12:27       ` Lars Ingebrigtsen
2022-09-03 13:03       ` Damien Cassou
2022-09-04  2:27     ` Michael Heerdegen
2022-09-04  8:44       ` Damien Cassou
2022-09-04 11:22         ` Lars Ingebrigtsen
2022-09-06  1:44         ` Michael Heerdegen
2022-09-03  1:42 ` Michael Heerdegen
2022-09-03  8:02   ` Damien Cassou

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).