summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-07-18 06:15:49 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-07-18 06:15:49 -0700
commit1fcd2951cbca8b1a72b0a7665032859139f03d10 (patch)
tree12e4d72a84f2f32495bd0a0e1790ebe1d92e52cb /lib.c
parent980942732a366f2042eac777b2d1e259a19d3652 (diff)
downloadtxr-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.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index cc0f923e..94e462ba 100644
--- a/lib.c
+++ b/lib.c
@@ -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);