all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Michael Heerdegen <michael_heerdegen@web.de>
To: Nicolas Petton <nicolas@petton.fr>
Cc: Emacs Devel <emacs-devel@gnu.org>
Subject: Re: Enhance seq-min and seq-max
Date: Sun, 16 Jun 2019 01:46:38 +0200	[thread overview]
Message-ID: <87wohm76ox.fsf@web.de> (raw)
In-Reply-To: <87a7ejelul.fsf_-_@web.de> (Michael Heerdegen's message of "Sat,  15 Jun 2019 02:25:06 +0200")

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

Michael Heerdegen <michael_heerdegen@web.de> writes:

> Like this, maybe?

Here is an update.  I improved the documentation and optimized the code
to avoid repeated calls of the KEY function on the same element.  There
are now more cases, but the code should be more efficient.

If this is accepted, I will care about the update of the manual.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-WIP-Enhance-seq-min-and-seq-max.patch --]
[-- Type: text/x-diff, Size: 3443 bytes --]

From 8c870d37e9f6c67f6eb1566cb1307465675b4d8a Mon Sep 17 00:00:00 2001
From: Michael Heerdegen <michael_heerdegen@web.de>
Date: Fri, 10 May 2019 15:08:57 +0200
Subject: [PATCH] WIP: Enhance seq-min and seq-max

---
 lisp/emacs-lisp/seq.el | 62 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 3413cd1513..b681adb393 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -451,15 +451,63 @@ seq-group-by
    (seq-reverse sequence)
    nil))

-(cl-defgeneric seq-min (sequence)
+(cl-defgeneric seq-min (sequence &optional predicate key)
   "Return the smallest element of SEQUENCE.
-SEQUENCE must be a sequence of numbers or markers."
-  (apply #'min (seq-into sequence 'list)))
-
-(cl-defgeneric seq-max (sequence)
+With PREDICATE given, use it to compare elements.
+With function KEY given, call it with the individual elements as
+arguments and compare the results instead of the elements.
+
+PREDICATE doesn't need to define a total order.  The return value is
+always the first element X of SEQUENCE so that for no following Y
+
+  (funcall PREDICATE (funcall KEY Y) (funcall KEY X))
+
+yields non-nil, where PREDICATE defaults to #'< and KEY to
+#'identity."
+  (if predicate
+      (if key
+          (let ((first (car sequence)))
+            (cdr (seq-reduce
+                  (lambda (key-x-and-x y)
+                    (let ((key-y-and-y (cons (funcall key y) y)))
+                      (if (funcall predicate (car key-y-and-y) (car key-x-and-x))
+                          key-y-and-y
+                        key-x-and-x)))
+                  (cdr sequence)
+                  (cons (funcall key first) first))))
+        (seq-reduce
+         (lambda (x y) (if (funcall predicate y x) y x))
+         (cdr sequence) (car sequence)))
+    (apply #'min (seq-into sequence 'list))))
+
+(cl-defgeneric seq-max (sequence &optional predicate key)
   "Return the largest element of SEQUENCE.
-SEQUENCE must be a sequence of numbers or markers."
-  (apply #'max (seq-into sequence 'list)))
+With PREDICATE given, use it to compare elements.
+With function KEY given, call it with the individual elements as
+arguments and compare the results instead of the elements.
+
+PREDICATE doesn't need to define a total order.  The return value is
+always the first element X of SEQUENCE so that for no following Y
+
+  (funcall PREDICATE (funcall KEY X) (funcall KEY Y))
+
+yields non-nil, where PREDICATE defaults to #'< and KEY to
+#'identity."
+  (if predicate
+      (if key
+          (let ((first (car sequence)))
+            (cdr (seq-reduce
+                  (lambda (key-x-and-x y)
+                    (let ((key-y-and-y (cons (funcall key y) y)))
+                      (if (funcall predicate (car key-x-and-x) (car key-y-and-y))
+                          key-y-and-y
+                        key-x-and-x)))
+                  (cdr sequence)
+                  (cons (funcall key first) first))))
+        (seq-reduce
+         (lambda (x y) (if (funcall predicate x y) y x))
+         (cdr sequence) (car sequence)))
+    (apply #'max (seq-into sequence 'list))))

 (defun seq--count-successive (pred sequence)
   "Return the number of successive elements for which (PRED element) is non-nil in SEQUENCE."
--
2.20.1


[-- Attachment #3: Type: text/plain, Size: 20 bytes --]



Thanks,

Michael.

  parent reply	other threads:[~2019-06-15 23:46 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-12 20:09 Emacs 26.2.90 is out! Nicolas Petton
2019-06-12 21:31 ` Nicolas Petton
2019-06-13 21:35 ` Phillip Lord
2019-06-13 23:03 ` stream.el (was: Emacs 26.2.90 is out!) Michael Heerdegen
2019-06-14  7:15   ` Nicolas Petton
2019-06-15  0:25     ` Enhance seq-min and seq-max (was: stream.el) Michael Heerdegen
2019-06-15  6:27       ` Eli Zaretskii
2019-06-15 23:00         ` Enhance seq-min and seq-max Michael Heerdegen
2019-06-16  2:38           ` Eli Zaretskii
2019-06-15 23:46       ` Michael Heerdegen [this message]
2019-06-16 20:11         ` Nicolas Petton
2019-06-16 23:21           ` Michael Heerdegen
2019-06-17  7:46             ` Nicolas Petton
2019-06-25 21:22               ` Michael Heerdegen
2019-06-26  7:52                 ` Nicolas Petton

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=87wohm76ox.fsf@web.de \
    --to=michael_heerdegen@web.de \
    --cc=emacs-devel@gnu.org \
    --cc=nicolas@petton.fr \
    /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.