summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-02-26 22:49:47 -0800
committerKaz Kylheku <kaz@kylheku.com>2024-02-26 22:49:47 -0800
commit06dfa00f02b6c816849dcee4e0dbc1133a3f6eb2 (patch)
tree3feba94614a85f94c3540bfc1d1a02060a3000b0 /lib.c
parent4a5554fad4cf85a3744baed1234164159ece310a (diff)
downloadtxr-06dfa00f02b6c816849dcee4e0dbc1133a3f6eb2.tar.gz
txr-06dfa00f02b6c816849dcee4e0dbc1133a3f6eb2.tar.bz2
txr-06dfa00f02b6c816849dcee4e0dbc1133a3f6eb2.zip
keep-keys-if: rework with generic sequence processing.
* lib.c (keep_keys_if): Replace with generic sequence iteration and building.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c68
1 files changed, 12 insertions, 56 deletions
diff --git a/lib.c b/lib.c
index f26fa6af..2f5a46ba 100644
--- a/lib.c
+++ b/lib.c
@@ -3281,69 +3281,25 @@ val keep_if(val pred, val seq, val keyfun)
return rem_if_impl(notf(pred), seq, keyfun, lit("keep-if"));
}
-val keep_keys_if(val pred, val seq_in, val keyfun_in)
+val keep_keys_if(val pred, val seq, val keyfun_in)
{
val self = lit("keep-keys-if");
val keyfun = default_null_arg(keyfun_in);
+ seq_iter_t it;
+ seq_build_t bu;
+ val elem;
- switch (type(seq_in)) {
- case NIL:
- return nil;
- case CONS:
- case LCONS:
- case COBJ:
- {
- list_collect_decl (out, ptail);
- val list = seq_in;
-
- gc_hint(list);
-
- for (; list; list = cdr(list)) {
- val elem = car(list);
- val key = keyfun ? funcall1(keyfun, elem) : elem;
-
- if (funcall1(pred, key))
- ptail = list_collect(ptail, key);
- }
- return out;
- }
- case LIT:
- case STR:
- case LSTR:
- {
- val out = mkustring(zero);
- val str = seq_in;
- cnum len = c_fixnum(length_str(str), self), i;
-
- for (i = 0; i < len; i++) {
- val elem = chr_str(str, num_fast(i));
- val key = keyfun ? funcall1(keyfun, elem) : elem;
-
- if (funcall1(pred, key))
- string_extend(out, key, tnil(i == len - 1));
- }
-
- return out;
- }
- case VEC:
- {
- val out = vector(zero, nil);
- val vec = seq_in;
- cnum len = c_fixnum(length_vec(vec), self), i;
-
- for (i = 0; i < len; i++) {
- val elem = vecref(vec, num_fast(i));
- val key = keyfun ? funcall1(keyfun, elem) : elem;
+ seq_iter_init(self, &it, seq);
+ seq_build_init(&bu, seq);
- if (funcall1(pred, key))
- vec_push(out, key);
- }
+ while (seq_get(&it, &elem)) {
+ val key = keyfun ? funcall1(keyfun, elem) : elem;
- return out;
- }
- default:
- uw_throwf(error_s, lit("~a: ~s isn't a sequence"), self, seq_in, nao);
+ if (funcall1(pred, key))
+ seq_add(&bu, key);
}
+
+ return seq_finish(&bu);
}
val separate(val pred, val seq_in, val keyfun_in)