[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Enhance seq-min and seq-max (was: stream.el)
From: |
Michael Heerdegen |
Subject: |
Enhance seq-min and seq-max (was: stream.el) |
Date: |
Sat, 15 Jun 2019 02:25:06 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) |
Nicolas Petton <address@hidden> writes:
> It's ok to fix them, but I'd like to stay involved at least.
Ok, great.
I would like to extend seq-min and seq-max to allow (a) arbitrary
comparison functions and (b) key functions like in cl, so that you can
find e.g. the longest string in a sequence of strings. I miss this
functionality, AFAIK cl-lib also can't do it.
Like this, maybe?
From 3cbaf1316de41687a6a3a6d67e4cc773769999c3 Mon Sep 17 00:00:00 2001
From: Michael Heerdegen <address@hidden>
Date: Fri, 10 May 2019 15:08:57 +0200
Subject: [PATCH] WIP: Enhance seq-min and seq-max
---
lisp/emacs-lisp/seq.el | 34 +++++++++++++++++++++++++++-------
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 3413cd1513..ddd8f3161c 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -451,15 +451,35 @@ 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. The default is
+`<'.
+With function KEY given, call it on the individual elements and
+compare the results instead of the elements."
+ (if predicate
+ (seq-reduce
+ (if key
+ (lambda (x y)
+ (if (funcall predicate (funcall key y) (funcall key x)) y x))
+ (lambda (x y) (if (funcall predicate y x) y x)))
+ 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. The default is
+`<'.
+With function KEY given, call it on the individual elements and
+compare the results instead of the elements."
+ (if predicate
+ (seq-reduce
+ (if key
+ (lambda (x y)
+ (if (funcall predicate (funcall key x) (funcall key y)) y x))
+ (lambda (x y) (if (funcall predicate x y) y x)))
+ 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
I made it so that if the result is ambiguous (e.g. multiple strings with
equal length), the first one is returned, but that is not explicitly
documented.
Regards,
Michael.
- Emacs 26.2.90 is out!, Nicolas Petton, 2019/06/12
- Re: Emacs 26.2.90 is out!, Nicolas Petton, 2019/06/12
- Re: Emacs 26.2.90 is out!, Phillip Lord, 2019/06/13
- stream.el (was: Emacs 26.2.90 is out!), Michael Heerdegen, 2019/06/13
- Re: Enhance seq-min and seq-max, Michael Heerdegen, 2019/06/15
- Re: Enhance seq-min and seq-max, Nicolas Petton, 2019/06/16
- Re: Enhance seq-min and seq-max, Michael Heerdegen, 2019/06/16
- Re: Enhance seq-min and seq-max, Nicolas Petton, 2019/06/17
- Re: Enhance seq-min and seq-max, Michael Heerdegen, 2019/06/25
- Re: Enhance seq-min and seq-max, Nicolas Petton, 2019/06/26