diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-02-21 03:08:11 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-02-21 03:08:11 -0800 |
commit | aad381bc6ce5458ef2483238066ae7fe1577d508 (patch) | |
tree | ce47953b39b6a1fadcbf45052cc79c83f55bdbf6 | |
parent | c914063fd0eb8c02d8362b86a61933c656a938bc (diff) | |
download | txr-aad381bc6ce5458ef2483238066ae7fe1577d508.tar.gz txr-aad381bc6ce5458ef2483238066ae7fe1577d508.tar.bz2 txr-aad381bc6ce5458ef2483238066ae7fe1577d508.zip |
New functions: find-max-key and find-min-key.
* eval.c (eval_init): Register find-max-key and find-min-key
intrinsics.
* lib.c (find_max_key, find_min_key): New functions.
* lib.h (find_max_key, find_min_key): Declared.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | lib.c | 30 | ||||
-rw-r--r-- | lib.h | 2 | ||||
-rw-r--r-- | stdlib/doc-syms.tl | 2 | ||||
-rw-r--r-- | txr.1 | 40 |
5 files changed, 76 insertions, 0 deletions
@@ -7340,7 +7340,9 @@ void eval_init(void) reg_fun(intern(lit("find-if"), user_package), func_n3o(find_if, 2)); reg_fun(intern(lit("rfind-if"), user_package), func_n3o(rfind_if, 2)); reg_fun(intern(lit("find-max"), user_package), func_n3o(find_max, 1)); + reg_fun(intern(lit("find-max-key"), user_package), func_n3o(find_max_key, 1)); reg_fun(intern(lit("find-min"), user_package), func_n3o(find_min, 1)); + reg_fun(intern(lit("find-min-key"), user_package), func_n3o(find_min_key, 1)); reg_fun(intern(lit("find-true"), user_package), func_n3o(find_true, 2)); reg_fun(intern(lit("multi-sort"), user_package), func_n3o(multi_sort, 2)); reg_fun(intern(lit("set-diff"), user_package), func_n4o(set_diff, 2)); @@ -10940,11 +10940,41 @@ val find_max(val seq, val testfun, val keyfun) } } +val find_max_key(val seq, val testfun_in, val keyfun_in) +{ + val self = lit("find-max-key"); + val testfun = default_arg(testfun_in, greater_f); + val keyfun = default_arg(keyfun_in, identity_f); + seq_iter_t iter; + val elem; + + seq_iter_init(self, &iter, seq); + + if (seq_get(&iter, &elem)) { + val maxkey = funcall1(keyfun, elem); + + while (seq_get(&iter, &elem)) { + val key = funcall1(keyfun, elem); + if (funcall2(testfun, key, maxkey)) + maxkey = key; + } + + return maxkey; + } + + return nil; +} + val find_min(val seq, val testfun, val keyfun) { return find_max(seq, default_arg(testfun, less_f), keyfun); } +val find_min_key(val seq, val testfun, val keyfun) +{ + return find_max_key(seq, default_arg(testfun, less_f), keyfun); +} + val find_true(val pred, val seq, val key) { val self = lit("find-true"); @@ -1197,7 +1197,9 @@ val rfind(val list, val key, val testfun, val keyfun); val find_if(val pred, val list, val key); val rfind_if(val pred, val list, val key); val find_max(val seq, val testfun, val keyfun); +val find_max_key(val seq, val testfun, val keyfun); val find_min(val seq, val testfun, val keyfun); +val find_min_key(val seq, val testfun, val keyfun); val find_true(val pred, val list, val keyfun); val posqual(val obj, val list); val rposqual(val obj, val list); diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl index 8a472752..d2af2cc1 100644 --- a/stdlib/doc-syms.tl +++ b/stdlib/doc-syms.tl @@ -740,7 +740,9 @@ ("find-frames" "N-02B97226") ("find-if" "N-00C9DFF6") ("find-max" "N-02BB4231") + ("find-max-key" "N-020038A0") ("find-min" "N-02BB4231") + ("find-min-key" "N-020038A0") ("find-package" "N-0250826D") ("find-struct-type" "N-01E5EEA7") ("find-symbol" "N-01EA8B50") @@ -35409,6 +35409,46 @@ the leftmost one is reported. See the notes under .code pos-max regarding duplicate maxima. +.coNP Functions @ find-max-key and @ find-min-key +.synb +.mets (find-max-key < iterable [ testfun <> [ keyfun ]]) +.mets (find-min-key < iterable [ testfun <> [ keyfun ]]) +.syne +.desc +The +.code find-min-key +and +.code find-max-key +functions have the same argument conventions as, respectively, +.code find-max +and +.code find-min +and agree with those functions in regard to which element of the +input sequence is identified: all these functions identify the +element which maximizes or minimizes the value of +.metn keyfun . + +Whereas +.code find-max +and +.code find-min +return the maximizing or minimizing element itself, the +.code find-max-key +and +.code find-min-key +functions return the value of +.meta keyfun +applied to the element. + +Under the default +.meta keyfun +value, that being the +.code identity +function, these functions behave the same as +.code find-max +and +.codn find-min . + .coNP Functions @, uni @, isec @ diff and @ symdiff .synb .mets (uni < iter1 < iter1 >> [ testfun <> [ keyfun ]]) |