diff options
-rw-r--r-- | lib.c | 81 | ||||
-rw-r--r-- | tests/012/seq.tl | 13 | ||||
-rw-r--r-- | txr.1 | 29 |
3 files changed, 36 insertions, 87 deletions
@@ -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) @@ -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. |