diff options
-rw-r--r-- | hash.c | 24 | ||||
-rw-r--r-- | hash.h | 2 | ||||
-rw-r--r-- | txr.1 | 15 |
3 files changed, 31 insertions, 10 deletions
@@ -1597,7 +1597,7 @@ val hash_alist(val hash) return make_lazy_cons_car(func_f1(iter, hash_alist_lazy), cell); } -val hash_uni(val hash1, val hash2, val joinfun) +val hash_uni(val hash1, val hash2, val joinfun, val map1fun, val map2fun) { val self = lit("hash-uni"); struct hash *h1 = coerce(struct hash *, cobj_handle(self, hash1, hash_s)); @@ -1615,21 +1615,29 @@ val hash_uni(val hash1, val hash2, val joinfun) hash_iter_init(&hi, hash2, self); for (entry = hash_iter_next(&hi); entry; entry = hash_iter_next(&hi)) { - sethash(hout, us_car(entry), us_cdr(entry)); + val rentry = us_cdr(entry); + if (!missingp(map2fun)) + rentry = funcall1(map2fun, rentry); + sethash(hout, us_car(entry), rentry); } hash_iter_init(&hi, hash1, self); for (entry = hash_iter_next(&hi); entry; entry = hash_iter_next(&hi)) { + val lentry = us_cdr(entry); + if (!missingp(map1fun)) + lentry = funcall1(map1fun, lentry); + if (missingp(joinfun)) { - sethash(hout, us_car(entry), us_cdr(entry)); + sethash(hout, us_car(entry), lentry); } else { val new_p; loc ptr = gethash_l(self, hout, us_car(entry), mkcloc(new_p)); - if (new_p) - sethash(hout, us_car(entry), us_cdr(entry)); - else - set(ptr, funcall2(joinfun, us_cdr(entry), deref(ptr))); + if (new_p) { + sethash(hout, us_car(entry), lentry); + } else { + set(ptr, funcall2(joinfun, lentry, deref(ptr))); + } } } @@ -1899,7 +1907,7 @@ void hash_init(void) reg_fun(intern(lit("hash-values"), user_package), func_n1(hash_values)); reg_fun(intern(lit("hash-pairs"), user_package), func_n1(hash_pairs)); reg_fun(intern(lit("hash-alist"), user_package), func_n1(hash_alist)); - reg_fun(intern(lit("hash-uni"), user_package), func_n3o(hash_uni, 2)); + reg_fun(intern(lit("hash-uni"), user_package), func_n5o(hash_uni, 2)); reg_fun(intern(lit("hash-diff"), user_package), func_n2(hash_diff)); reg_fun(intern(lit("hash-symdiff"), user_package), func_n2(hash_symdiff)); reg_fun(intern(lit("hash-isec"), user_package), func_n3o(hash_isec, 2)); @@ -80,7 +80,7 @@ val hash_keys(val hash); val hash_values(val hash); val hash_pairs(val hash); val hash_alist(val hash); -val hash_uni(val hash1, val hash2, val joinfun); +val hash_uni(val hash1, val hash2, val joinfun, val lunitfun, val runitfun); val hash_diff(val hash1, val hash2); val hash_symdiff(val hash1, val hash2); val hash_isec(val hash1, val hash2, val joinfun); @@ -45819,7 +45819,7 @@ or .coNP Functions @, hash-uni @, hash-diff @ hash-symdiff and @ hash-isec .synb -.mets (hash-uni < hash1 < hash2 <> [ joinfun ]) +.mets (hash-uni < hash1 < hash2 >> [ joinfun >> [ map1fun <> [ map2fun ]]]) .mets (hash-diff < hash1 << hash2 ) .mets (hash-symdiff < hash1 << hash2 ) .mets (hash-isec < hash1 < hash2 <> [ joinfun ]) @@ -45872,6 +45872,19 @@ and .metn hash2 . The return value of this function is used as the value in the union hash. +If +.meta map1fun +is specified it must be a function that can be called with one +argument. All values from +.meta hash1 +are projected through this function: the function is applied +to each value, and the function's return value is used +in place of the original value. +Similarly, if +.meta map2fun +is present, specifies a function through which values from +.meta hash2 +are projected. The .code hash-diff |