summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-11-21 22:09:22 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-11-21 22:09:22 -0800
commit881c54cb71ef28948a81b2890769828c2dc58cfd (patch)
tree70a9a0926bfba42ddb4951b6b065a8f3f89b2aa1
parentc36bd9667e8905aeef9c01660c2adb74782ce3ce (diff)
downloadtxr-881c54cb71ef28948a81b2890769828c2dc58cfd.tar.gz
txr-881c54cb71ef28948a81b2890769828c2dc58cfd.tar.bz2
txr-881c54cb71ef28948a81b2890769828c2dc58cfd.zip
* eval.c (eval_init): Register sort-group.
* lib.c (sort_group): New function. * lib.h (sort_group): Declared. * txr.1: Documented.
-rw-r--r--ChangeLog10
-rw-r--r--eval.c1
-rw-r--r--lib.c10
-rw-r--r--lib.h1
-rw-r--r--txr.132
5 files changed, 53 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 932dc26c..ee5a3e17 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2014-11-21 Kaz Kylheku <kaz@kylheku.com>
+ * eval.c (eval_init): Register sort-group.
+
+ * lib.c (sort_group): New function.
+
+ * lib.h (sort_group): Declared.
+
+ * txr.1: Documented.
+
+2014-11-21 Kaz Kylheku <kaz@kylheku.com>
+
* lib.c (partition_star_func): Bugfix: doing rplaca(env, seq)
too early, before the loop which adjusts its value.
Restructuring this slightly to avoid duplicated code, by moving the
diff --git a/eval.c b/eval.c
index ef9b5cd7..1a1fb0c2 100644
--- a/eval.c
+++ b/eval.c
@@ -3774,6 +3774,7 @@ void eval_init(void)
reg_fun(intern(lit("hash-diff"), user_package), func_n2(hash_diff));
reg_fun(intern(lit("hash-isec"), user_package), func_n3o(hash_isec, 2));
reg_fun(intern(lit("group-by"), user_package), func_n2v(group_by));
+ reg_fun(intern(lit("sort-group"), user_package), func_n3o(sort_group, 1));
reg_fun(intern(lit("uniq"), user_package), func_n1(uniq));
reg_fun(intern(lit("hash-update"), user_package), func_n2(hash_update));
reg_fun(intern(lit("hash-update-1"), user_package),
diff --git a/lib.c b/lib.c
index 53f645ef..13c9d388 100644
--- a/lib.c
+++ b/lib.c
@@ -5695,6 +5695,15 @@ val multi_sort(val lists, val funcs, val key_funcs)
return mapcarv(list_f, tuples);
}
+val sort_group(val seq, val keyfun, val lessfun)
+{
+ val kf = default_arg(keyfun, identity_f);
+ val lf = default_arg(lessfun, less_f);
+ val seq_copy = copy(seq);
+ val sorted = sort(seq_copy, lf, kf);
+ return partition_by(kf, sorted);
+}
+
val uniq(val seq)
{
val hash = make_hash(nil, nil, t);
@@ -5727,7 +5736,6 @@ val uniq(val seq)
return make_like(out, seq);
}
-
val find(val item, val list, val testfun, val keyfun)
{
testfun = default_arg(testfun, equal_f);
diff --git a/lib.h b/lib.h
index c5c187ff..03a972fa 100644
--- a/lib.h
+++ b/lib.h
@@ -796,6 +796,7 @@ val interpose(val sep, val seq);
val merge(val list1, val list2, val lessfun, val keyfun);
val sort(val seq, val lessfun, val keyfun);
val multi_sort(val lists, val funcs, val key_funcs);
+val sort_group(val seq, val keyfun, val lessfun);
val uniq(val seq);
val find(val list, val key, val testfun, val keyfun);
val find_if(val pred, val list, val key);
diff --git a/txr.1 b/txr.1
index 8c950bad..a9b2d138 100644
--- a/txr.1
+++ b/txr.1
@@ -17676,6 +17676,38 @@ For strings and vectors,
.code sort
is not stable.
+.coNP Function sort-group
+.synb
+.mets (sort-group < sequence >> [ keyfun <> [ lessfun ]])
+.syne
+.desc
+The
+.code sort-group
+function sorts
+.meta sequence
+according to the
+.meta keyfun
+and
+.meta lessfun
+arguments, and then breaks the resulting sequence into groups,
+based on the equivalence of the elements under
+.metn keyfun .
+
+The following equivalence holds:
+
+.cblk
+ (sort-group sq lf kf) <--> (partition-by kf (sort (copy sq) kf lf))
+.cble
+
+Note the reversed order of
+.meta keyfun
+and
+.meta lessfun
+arguments between
+.code sort
+and
+.codn sort-group .
+
.coNP Function @ uniq
.synb
.mets (uniq << sequence )