diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-07-30 08:11:02 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-07-30 08:11:02 -0700 |
commit | af0cf3c74a55872b259a1a3f2f0bc604d2aa12e5 (patch) | |
tree | 2bbe7c1956085599141847470bdbef7de04adc3f /lib.c | |
parent | cdbd2695fc3896034562aab2e47b3476dc401077 (diff) | |
download | txr-af0cf3c74a55872b259a1a3f2f0bc604d2aa12e5.tar.gz txr-af0cf3c74a55872b259a1a3f2f0bc604d2aa12e5.tar.bz2 txr-af0cf3c74a55872b259a1a3f2f0bc604d2aa12e5.zip |
keep-if, remove-if, keep-keys-if: mapfun argument.
We introduce a mapfun argument to these functions so that they
can additionally transform the accumulated values.
The keep-keys-if function is now implemented through the same
helper function as keep-if but with the mapfun argument
defaulting to a copy of the keyfun argument.
* eval.c (eval_init): Update registrations of remove-if,
keep-if and keep-keys-if to new arities of C functions.
* lib.c (rem_if_impl): Implement new optional mapfun
parameter.
(remove_if, keep_if): Add mapfun parameter.
(keep_keys_if): Implement via rem_if_impl, and add
mapfun argument. We do the defaulting of keyfun here,
so that we can then use that argument's value to default
mapfun.
* lib.h (remove_if, keep_if, keep_keys_if): Declarations
updated.
* tests/012/seq.tl: Couple of test cases exercising mapfun
argument of keep-if and remove-if.
* txr.1: Documented.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 42 |
1 files changed, 18 insertions, 24 deletions
@@ -3418,9 +3418,11 @@ static val rem_impl(val (*eqfun)(val, val), val self, return seq_finish(&bu); } -static val rem_if_impl(val pred, val seq, val keyfun_in, val self) +static val rem_if_impl(val pred, val seq, val keyfun_in, val mapfun_in, + val self) { val keyfun = default_null_arg(keyfun_in); + val mapfun = default_null_arg(mapfun_in); seq_iter_t it; seq_build_t bu; val elem; @@ -3430,8 +3432,15 @@ static val rem_if_impl(val pred, val seq, val keyfun_in, val self) while (seq_get(&it, &elem)) { val key = keyfun ? funcall1(keyfun, elem) : elem; - if (!funcall1(pred, key)) + if (!funcall1(pred, key)) { + if (mapfun) { + if (mapfun == keyfun) + elem = key; + else + elem = funcall1(mapfun, elem); + } seq_add(&bu, elem); + } } return seq_finish(&bu); @@ -3467,35 +3476,20 @@ val keepqual(val obj, val seq, val keyfun) return rem_impl(nequal, lit("keepqual"), obj, seq, keyfun); } -val remove_if(val pred, val seq, val keyfun) +val remove_if(val pred, val seq, val keyfun, val mapfun) { - return rem_if_impl(pred, seq, keyfun, lit("remove-if")); + return rem_if_impl(pred, seq, keyfun, mapfun, lit("remove-if")); } -val keep_if(val pred, val seq, val keyfun) +val keep_if(val pred, val seq, val keyfun, val mapfun) { - return rem_if_impl(notf(pred), seq, keyfun, lit("keep-if")); + return rem_if_impl(notf(pred), seq, keyfun, mapfun, lit("keep-if")); } -val keep_keys_if(val pred, val seq, val keyfun_in) +val keep_keys_if(val pred, val seq, val keyfun_in, val mapfun_in) { - val self = lit("keep-keys-if"); - val keyfun = default_null_arg(keyfun_in); - seq_iter_t it; - seq_build_t bu; - val elem; - - seq_iter_init(self, &it, seq); - seq_build_init(self, &bu, seq); - - while (seq_get(&it, &elem)) { - val key = keyfun ? funcall1(keyfun, elem) : elem; - - if (funcall1(pred, key)) - seq_add(&bu, key); - } - - return seq_finish(&bu); + val mapfun = default_arg(mapfun_in, keyfun_in); + return rem_if_impl(notf(pred), seq, keyfun_in, mapfun, lit("keep-keys-if")); } val separate(val pred, val seq, val keyfun_in) |