summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib.c81
-rw-r--r--tests/012/seq.tl13
-rw-r--r--txr.129
3 files changed, 36 insertions, 87 deletions
diff --git a/lib.c b/lib.c
index ba8dca50..2d331a9f 100644
--- a/lib.c
+++ b/lib.c
@@ -10865,79 +10865,32 @@ val rfind(val item, val seq, val testfun_in, val keyfun_in)
}
}
-val find_max(val seq, val testfun, val keyfun)
+val find_max(val seq, val testfun_in, val keyfun_in)
{
val self = lit("find-max");
- seq_info_t si = seq_info(seq);
- testfun = default_arg(testfun, greater_f);
- keyfun = default_arg(keyfun, identity_f);
-
- switch (si.kind) {
- case SEQ_NIL:
- return nil;
- case SEQ_HASHLIKE:
- {
- struct hash_iter hi;
- val cell = (hash_iter_init(&hi, si.obj, self), hash_iter_next(&hi));
- val maxelt = cell;
- val maxkey = if2(cell, funcall1(keyfun, cell));
-
- while (cell && (cell = hash_iter_next(&hi))) {
- val key = funcall1(keyfun, cell);
- if (funcall2(testfun, key, maxkey)) {
- maxkey = key;
- maxelt = cell;
- }
- }
+ val testfun = default_arg(testfun_in, greater_f);
+ val keyfun = default_arg(keyfun_in, identity_f);
+ seq_iter_t iter;
+ val elem;
- return maxelt;
- }
- case SEQ_LISTLIKE:
- {
- val maxelt = car(z(si.obj));
- val maxkey = funcall1(keyfun, maxelt);
+ seq_iter_init(self, &iter, seq);
- gc_hint(seq);
+ if (seq_get(&iter, &elem)) {
+ val maxkey = funcall1(keyfun, elem);
+ val maxelem = elem;
- for (seq = cdr(seq); seq; seq = cdr(seq)) {
- val elt = car(seq);
- val key = funcall1(keyfun, elt);
- if (funcall2(testfun, key, maxkey)) {
- maxkey = key;
- maxelt = elt;
- }
+ while (seq_get(&iter, &elem)) {
+ val key = funcall1(keyfun, elem);
+ if (funcall2(testfun, key, maxkey)) {
+ maxkey = key;
+ maxelem = elem;
}
-
- return maxelt;
}
- case SEQ_VECLIKE:
- {
- val vec = si.obj;
- cnum len = c_fixnum(length(vec), self);
- if (len > 0) {
- val maxelt = ref(vec, zero);
- val maxkey = funcall1(keyfun, maxelt);
- cnum i;
-
- for (i = 1; i < len; i++) {
- val elt = ref(vec, num_fast(i));
- val key = funcall1(keyfun, elt);
- if (funcall2(testfun, key, maxkey)) {
- maxkey = key;
- maxelt = elt;
- }
- }
-
- return maxelt;
- }
-
- return nil;
- }
- case SEQ_NOTSEQ:
- default:
- unsup_obj(self, seq);
+ return maxelem;
}
+
+ return nil;
}
val find_max_key(val seq, val testfun_in, val keyfun_in)
diff --git a/tests/012/seq.tl b/tests/012/seq.tl
index 1bc45b55..3c56dfda 100644
--- a/tests/012/seq.tl
+++ b/tests/012/seq.tl
@@ -445,3 +445,16 @@
(pairlis "" #(1 2 3)) nil
(pairlis "abcd" #()) nil
(pairlis '(1 2 3) '(a b c) '(4 5 6)) ((1 . a) (2 . b) (3 . c) 4 5 6))
+
+(mtest
+ (find-max nil) nil
+ [find-max '("alpha" "charlie" "aardvark" "bravo") less] "aardvark"
+ [find-max '("alpha" "charlie" "aardvark" "bravo") less reverse] "alpha"
+ [find-max '("alpha" "charlie" "aardvark" "bravo") : reverse] "bravo"
+ (find-max 1..10) 9
+ [find-max #H(() (a 1) (b 2) (c 3)) : cdr] (c . 3))
+
+(mtest
+ (find-max-key nil) nil
+ [find-max-key '("alpha" "charlie" "aardvark" "bravo") less upcase-str] "AARDVARK"
+ [find-max-key #H(() (a 1) (b 2) (c 3)) : cdr] 3)
diff --git a/txr.1 b/txr.1
index 9ab36a25..fb8c7bfb 100644
--- a/txr.1
+++ b/txr.1
@@ -35318,8 +35318,8 @@ a hash table can change when other items are inserted or deleted.
.coNP Functions @ find-max and @ find-min
.synb
-.mets (find-max >> { sequence | << hash } >> [ testfun <> [ keyfun ]])
-.mets (find-min >> { sequence | << hash } >> [ testfun <> [ keyfun ]])
+.mets (find-max < iterable >> [ testfun <> [ keyfun ]])
+.mets (find-min < iterable >> [ testfun <> [ keyfun ]])
.syne
.desc
The
@@ -35347,7 +35347,7 @@ argument, the
.code find-max
function finds the numerically
maximum value occurring in
-.metn sequence ,
+.metn iterable ,
whereas
.code pos-min
without a
@@ -35382,30 +35382,13 @@ is passed through this one-argument function, and
the resulting value is used in its place for the purposes of the
comparison. However, the original element is returned.
-A hash table may be specified instead of a sequence.
-The
-.meta hash
-is treated as if it were a sequence of hash key and hash
-value pairs represented as cons cells, the
-.code car
-slots of which are the hash keys, and the
-.code cdr
-of which are the hash values. If the caller doesn't specify a
-.meta keyfun
-then these cells are taken as their keys. To find the hash
-table's key-value cell with the maximum key, the
-.code car
-function can be specified as
-.metn keyfun .
-To find the entry holding the maximum value, the
-.code cdr
-function can be specified.
-
If there are multiple equivalent maxima, then under the default
.metn testfun ,
that being
.codn less ,
-the leftmost one is reported. See the notes under
+the first one encountered while traversing
+.meta iterable
+is the one that is reported. See the notes under
.code pos-max
regarding duplicate maxima.