summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index f5a3d920..b56a4a5b 100644
--- a/lib.c
+++ b/lib.c
@@ -9994,6 +9994,49 @@ val set_diff(val list1, val list2, val testfun, val keyfun)
return make_like(out, list_orig);
}
+val symdiff(val seq1, val seq2, val testfun, val keyfun)
+{
+ val self = lit("symdiff");
+ list_collect_decl (out, ptail);
+ seq_iter_t si1, si2;
+ val el1, el2;
+
+ testfun = default_arg(testfun, equal_f);
+ keyfun = default_arg(keyfun, identity_f);
+
+ seq_iter_init(self, &si1, seq1);
+ seq_iter_init(self, &si2, seq2);
+
+ while (seq_get(&si1, &el1))
+ ptail = list_collect(ptail, el1);
+
+ while (seq_get(&si2, &el2)) {
+ val el2_key = funcall1(keyfun, el2);
+ val *iter;
+ int found = 0;
+
+ for (iter = &out; *iter; ) {
+ val elo = us_car(*iter);
+ val elo_key = funcall1(keyfun, elo);
+ if (funcall2(testfun, elo_key, el2_key)) {
+ val del = us_cdr(*iter);
+ if (deref(ptail) == del)
+ ptail = mkcloc(*iter);
+ *iter = del;
+ found = 1;
+ break;
+ } else {
+ iter = us_cdr_p(*iter);
+ }
+ }
+
+ if (!found)
+ ptail = list_collect(ptail, el2);
+ }
+
+ return make_like(out, seq1);
+}
+
val isec(val seq1, val seq2, val testfun, val keyfun)
{
val self = lit("isec");