From: Damien Cassou <damien@cassou.me>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 57548@debbugs.gnu.org
Subject: bug#57548: Add new function `seq-positions'
Date: Sat, 03 Sep 2022 10:01:26 +0200 [thread overview]
Message-ID: <87a67gubs9.fsf@cassou.me> (raw)
In-Reply-To: <83sfl9ob41.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 2377 bytes --]
Eli Zaretskii <eliz@gnu.org> writes:
> We use "index", not "position".
I changed the text in the manual, NEWS and docstring to talk about
"index" instead of "position". I kept the word "positions" in the
function name because there is already a `seq-position` function and the
2 are so similar that I think they deserve a similar name. What do you
think?
> In any case, the documentation should explain what you mean by that,
I haven't found another such explanation in seq.texi so I'm not sure
what you means. I would be happy to write something if you feel
something is still missing though.
> and it should definitely say that the index/position are zero-based.
done in the manual, NEWS and docstring.
>> +@group
>> +(seq-position '(a b c a d) 'z)
>> +@result{} nil
>
> seq-position or seq-positions?
you are so right. Thank you for the careful review.
> Our style is to say
> Equality is defined by the function TESTFN, which defaults to `equal'.
fixed. If you want, I can prepare another patch to apply the same
change to the docstring of the already existing `seq-position`: it
contains the same phrasing.
>> +(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)))))
>
> Should we test more than just one type of sequences?
The `with-test-sequences` call checks 3 types of sequences already as
far as I understand. Do you mean something else?
Michael Heerdegen <michael_heerdegen@web.de> writes:
> We do not need to limit this to equivalence relations. A TESTFUN of, say,
> (apply-partially #'<= 10) could be similarly useful.
Indeed, such a function would certainly make sense. I would refrain
from calling it `seq-positions` though because there is already a
`seq-position` function that is very similar. I guess the function you
suggest wouldn't take an element as argument either. In any case, I
think the current function makes sense on its own and what you are
asking for is a new function that seems out of scope of this current
patch. If you give me a name (what about `(seq-matching-positions seq
pred)`?), I volunteer to send a new patch in a new mail thread.
Best
--
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/x-patch, Size: 4069 bytes --]
From e3c696f73b37da24eb3883d365a72f014a3e52ee 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 | 13 +++++++++++++
lisp/emacs-lisp/shortdoc.el | 3 +++
test/lisp/emacs-lisp/seq-tests.el | 5 +++++
5 files changed, 43 insertions(+)
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 1f6f80521c..6b198ba731 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 (zero-based) indices 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-positions '(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..a8fc8dcc34 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 (zero-based) indices 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..7e8576fffb 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -445,6 +445,19 @@ seq-position
(setq index (1+ index)))
nil)))
+;;;###autoload
+(cl-defgeneric seq-positions (sequence elt &optional testfn)
+ "Return a list of the (zero-based) indices of ELT in SEQ.
+Equality is defined by the function TESTFN, which defaults to
+`equal'."
+ (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.
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
next prev parent reply other threads:[~2022-09-03 8:01 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87a67gubs9.fsf@cassou.me \
--to=damien@cassou.me \
--cc=57548@debbugs.gnu.org \
--cc=eliz@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.