diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-07-18 06:15:49 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-07-18 06:15:49 -0700 |
commit | 1fcd2951cbca8b1a72b0a7665032859139f03d10 (patch) | |
tree | 12e4d72a84f2f32495bd0a0e1790ebe1d92e52cb /lib.c | |
parent | 980942732a366f2042eac777b2d1e259a19d3652 (diff) | |
download | txr-1fcd2951cbca8b1a72b0a7665032859139f03d10.tar.gz txr-1fcd2951cbca8b1a72b0a7665032859139f03d10.tar.bz2 txr-1fcd2951cbca8b1a72b0a7665032859139f03d10.zip |
New function: count.
The general count function, with keyfun and testfun,
is noticeably absent. Let's implement it.
* lib.[ch] (count): New function.
* eval.c (eval_init): Register count intrinsic.
* tests/012/seq.tl: Some tests for count.
* txr.1: Add count to count-if section. Revise documentation
based on pos/pos-if.
* stdlib/doc-syms.tl: Updated.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 25 |
1 files changed, 25 insertions, 0 deletions
@@ -3373,6 +3373,31 @@ val count_if(val pred, val seq, val key_in) plus(unum(count), ash(ocount, num_fast(CHAR_BIT * sizeof count)))); } +val count(val item, val seq, val testfun_in, val keyfun_in) +{ + val self = lit("count"); + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); + seq_iter_t iter; + ucnum count = 0; + val ocount = zero; + val elem; + + seq_iter_init(self, &iter, z(seq)); + + while (seq_get(&iter, &elem)) { + val subj = funcall1(keyfun, elem); + if (funcall2(testfun, item, subj)) + if (++count == 0) + ocount = plus(ocount, one); + } + + return if3(ocount == zero, + unum(count), + plus(unum(count), ash(ocount, num_fast(CHAR_BIT * sizeof count)))); + +} + val some_satisfy(val seq, val pred_in, val key_in) { val pred = default_arg(pred_in, identity_f); |