diff options
-rw-r--r-- | genman.txr | 2 | ||||
-rw-r--r-- | hash.c | 14 | ||||
-rw-r--r-- | hash.h | 1 | ||||
-rw-r--r-- | stdlib/doc-syms.tl | 1 | ||||
-rw-r--r-- | tests/010/hash.tl | 3 | ||||
-rw-r--r-- | txr.1 | 32 |
6 files changed, 53 insertions, 0 deletions
@@ -13,6 +13,7 @@ (defvarl tagnum (hash :equal-based)) (defvarl disamb (hash :equal-based)) (defvarl dist-counter 0) + (defvarl colli (hash-props "Function <tt>hash-map</tt>" 1)) (defun hash-str (str) (for ((lim (len str)) (i 0) (h 0) g) ((< i lim) h) ((inc i)) @@ -22,6 +23,7 @@ (defun hash-title (title) (let* ((h (logtrunc (hash-str title) 32)) + (h (+ h (or [colli title] 0))) (existing [dupes h])) (when existing (unless (equal title existing) @@ -1694,6 +1694,19 @@ val hash_from_alist_v(val alist, struct args *hashv_args) return hash; } +val hash_map(val fun, val seq, struct args *hashv_args) +{ + val self = lit("hash-map"); + seq_iter_t iter; + val hash = hashv(hashv_args), elem; + seq_iter_init(self, &iter, seq); + + while (seq_get(&iter, &elem)) + sethash(hash, elem, funcall1(fun, elem)); + + return hash; +} + val hash_props(struct args *plist) { val self = lit("hash-props"); @@ -2222,6 +2235,7 @@ void hash_init(void) reg_fun(hash_construct_s, func_n2(hash_construct)); reg_fun(intern(lit("hash-from-pairs"), user_package), func_n1v(hash_from_pairs_v)); reg_fun(intern(lit("hash-from-alist"), user_package), func_n1v(hash_from_alist_v)); + reg_fun(intern(lit("hash-map"), user_package), func_n2v(hash_map)); reg_fun(intern(lit("hash-props"), user_package), func_n0v(hash_props)); reg_fun(intern(lit("hash-list"), user_package), func_n1v(hash_list)); reg_fun(intern(lit("hash-zip"), user_package), func_n2v(hash_zip)); @@ -83,6 +83,7 @@ val hashl(val args); val hash_construct(val hashl_args, val pairs); val hash_from_pairs_v(val pairs, struct args *hashv_args); val hash_from_alist_v(val alist, struct args *hashv_args); +val hash_map(val fun, val seq, struct args *hashv_args); val hash_props(struct args *plist); val hash_list(val keys, struct args *hashv_args); val hash_zip(val keys, val vals, struct args *hashv_args); diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl index a46abbd0..4d4ee04d 100644 --- a/stdlib/doc-syms.tl +++ b/stdlib/doc-syms.tl @@ -952,6 +952,7 @@ ("hash-keys" "N-00C9B125") ("hash-keys-of" "N-02FBE776") ("hash-list" "N-02EE9235") + ("hash-map" "N-027671E9") ("hash-next" "N-0225209D") ("hash-pairs" "N-00C9B125") ("hash-peek" "N-0225209D") diff --git a/tests/010/hash.tl b/tests/010/hash.tl index 5af8b167..db8f07aa 100644 --- a/tests/010/hash.tl +++ b/tests/010/hash.tl @@ -60,3 +60,6 @@ (let ((items (build (whilet ((cell (hash-next i))) (add (car cell)))))) (test (diff 0..200 items) nil)))) + +(test [hash-map square '(1 2 3)] + #H(() (1 1) (2 4) (3 9))) @@ -55848,6 +55848,38 @@ The returned hash table is and no parameters are available for customizing any of its properties, such as weakness. +.coNP Function @ hash-map +.synb +.mets (hash-map < fun < sequence << hash-arg *) +.syne +.desc +The +.code hash-map +function constructs a function out of a +.metn sequence . +The +.meta fun +argument must be a function that can be called with one argument. + +The elements of +.meta sequence +become the hash keys. The value associated with each key +is determined by passing that value to function +.meta fun +and taking the returned value. + +The remaining +.meta hash-arg +arguments determine what kind of hash table is created, +as if they were applied to the +.code hash +function. + +If the sequence contains duplicate elements (according to the +hash table equality in effect for the hash table being +constructed), duplicate elements later in the sequence +replace earlier elements. + .coNP Function @ hash-update .synb .mets (hash-update < hash << function ) |