diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | hash.c | 29 | ||||
-rw-r--r-- | hash.h | 1 | ||||
-rw-r--r-- | txr.1 | 31 |
5 files changed, 72 insertions, 0 deletions
@@ -1,5 +1,15 @@ 2014-01-16 Kaz Kylheku <kaz@kylheku.com> + * hash.c (group_by): New function. + + * hash.h (group_by): Declared. + + * eval.c (eval_init): group_by registered as group-by intrinsic. + + * txr.1: Documented. + +2014-01-16 Kaz Kylheku <kaz@kylheku.com> + Version 75 * txr.c (version): Bumped. @@ -2437,6 +2437,7 @@ void eval_init(void) reg_fun(intern(lit("hash-uni"), user_package), func_n2(hash_uni)); reg_fun(intern(lit("hash-diff"), user_package), func_n2(hash_diff)); reg_fun(intern(lit("hash-isec"), user_package), func_n2(hash_isec)); + reg_fun(intern(lit("group-by"), user_package), func_n2v(group_by)); reg_fun(intern(lit("eval"), user_package), func_n2o(eval_intrinsic, 1)); reg_fun(intern(lit("lisp-parse"), user_package), func_n2o(lisp_parse, 0)); @@ -684,6 +684,35 @@ val hash_construct(val hashv_args, val pairs) return hash; } +val group_by(val func, val seq, val hashv_args) +{ + val hash = hashv(hashv_args); + + if (vectorp(seq)) { + cnum i, len; + + for (i = 0, len = c_num(length(seq)); i < len; i++) { + val v = vecref(seq, num_fast(i)); + pushhash(hash, funcall1(func, v), v); + } + } else { + for (; seq; seq = cdr(seq)) { + val v = car(seq); + pushhash(hash, funcall1(func, v), v); + } + } + + { + val iter = hash_begin(hash); + val cell; + + while ((cell = hash_next(iter)) != nil) + rplacd(cell, nreverse(cdr(cell))); + + return hash; + } +} + static val hash_keys_lazy(val iter, val lcons) { val cell = hash_next(iter); @@ -47,6 +47,7 @@ val hash_eql(val obj); val hash_equal(val obj); val hashv(val args); val hash_construct(val hashv_args, val pairs); +val group_by(val func, val seq, val hashv_args); val hash_keys(val hash); val hash_values(val hash); val hash_pairs(val hash); @@ -9656,6 +9656,37 @@ the equal function instead. In addition to storing key-value pairs, a hash table can have a piece of information associated with it, called the user data. +.SS Function group-by + +.TP +Syntax: + + (group-by <func> <sequence> . <options>) + +.TP +Description: + +The group-by function produces a hash table from <sequence>, which is a +list or vector. Entries of the hash table are not elements of sequence, +but lists of elements of <sequence>. The function <func> is applied toe +each element of <sequence> to compute a key. That key is used to determine +which list the item is added to in the hash table. + +The trailing arguments <options>, if any, consist of the same keywords +that are understood by the hash function, and determine the properties +of the hash. + +.TP +Example: + +Group the integers from 0 to 10 into three buckets keyed on 0, 1 and 2 +according to the modulo 3 congruence: + + (group-by (op mod @1 3) (range 0 10))) + + -> #H(() (0 (0 3 6 9)) (1 (1 4 7 10)) (2 (2 5 8))) + + .SS Functions make-similar-hash and copy-hash .TP |