diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-02-22 07:43:47 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-02-22 07:43:47 -0800 |
commit | e987585d08122ecf3448a2d432346d2e128e5926 (patch) | |
tree | 582bcfcb1881c471578b598d62ad38429ade3d84 /lib.c | |
parent | c38dbf7975d0df4758b295b90a47c1dbaaeaa976 (diff) | |
download | txr-e987585d08122ecf3448a2d432346d2e128e5926.tar.gz txr-e987585d08122ecf3448a2d432346d2e128e5926.tar.bz2 txr-e987585d08122ecf3448a2d432346d2e128e5926.zip |
find-max: convert to seq_info iteration.
* lib.c (find_max): Simplify into a single loop rather than
handling various sequence types specially. This means it
works for all iterable objects now.
* txr.1: find-max documentation updated; discussion of
hash tables removed, since the described behavior is the
one expected for hash tables as iterables.
* tests/012/seq.tl: Add some test coverage.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 81 |
1 files changed, 17 insertions, 64 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) |