From 9a2f9df335393284f6af2d95dbd65cb606792ad8 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 20 Jan 2021 01:03:51 -0800 Subject: New function: hash-keys-of. * hash.c (hash_keys_of): New function. (hash_init): Register hash-keys-of intrinsic * hash.h (hash_keys_of): Declared. * txr.1: Documented. --- hash.c | 21 +++++++++++++++++++++ hash.h | 1 + txr.1 | 11 ++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/hash.c b/hash.c index a6772c29..8040fa68 100644 --- a/hash.c +++ b/hash.c @@ -1808,6 +1808,26 @@ val hash_revget(val hash, val value, val test, val keyfun) return nil; } +val hash_keys_of(val hash, val value, val test, val keyfun) +{ + val self = lit("hash-keys-of"); + val cell; + struct hash_iter hi; + list_collect_decl(out, ptail); + + hash_iter_init(&hi, hash, self); + + test = default_arg(test, eql_f); + keyfun = default_arg(keyfun, identity_f); + + while ((cell = hash_iter_next(&hi)) != nil) { + if (funcall2(test, value, funcall1(keyfun, us_cdr(cell)))) + ptail = list_collect(ptail, us_car(cell)); + } + + return out; +} + val hash_invert(val hash, val joinfun, val unitfun, struct args *hashv_args) { val self = lit("hash-invert"); @@ -1916,6 +1936,7 @@ void hash_init(void) reg_fun(intern(lit("hash-update-1"), user_package), func_n4o(hash_update_1, 3)); reg_fun(intern(lit("hash-revget"), user_package), func_n4o(hash_revget, 2)); + reg_fun(intern(lit("hash-keys-of"), user_package), func_n4o(hash_keys_of, 2)); reg_fun(intern(lit("hash-invert"), user_package), func_n3ov(hash_invert, 1)); reg_fun(intern(lit("hash-begin"), user_package), func_n1(hash_begin)); reg_fun(intern(lit("hash-next"), user_package), func_n1(hash_next)); diff --git a/hash.h b/hash.h index f9fcb75b..542b3e1a 100644 --- a/hash.h +++ b/hash.h @@ -89,6 +89,7 @@ val hash_proper_subset(val hash1, val hash2); val hash_update(val hash, val fun); val hash_update_1(val hash, val key, val fun, val init); val hash_revget(val hash, val value, val test, val keyfun); +val hash_keys_of(val hash, val value, val test, val keyfun); val hash_invert(val hash, val joinfun, val unitfun, struct args *hashv_args); void hash_process_weak(void); diff --git a/txr.1 b/txr.1 index 54550b31..bf1233e2 100644 --- a/txr.1 +++ b/txr.1 @@ -48244,9 +48244,10 @@ to The function returns .codn nil . -.coNP Function @ hash-revget +.coNP Functions @ hash-revget and @ hash-keys-of .synb .mets (hash-revget < hash < value >> [ testfun <> [ keyfun ]]) +.mets (hash-keys-of < hash < value >> [ testfun <> [ keyfun ]]) .syne .desc The @@ -48267,6 +48268,14 @@ is returned. If multiple matching entries exist, it is not specified which entry's key is returned. +The +.code hash-keys-of +function has exactly the same argument conventions, and likewise +searches the +.metn hash . +However, it returns a list of all keys whose values match +.metn value . + The .meta keyfun function is applied to each value in -- cgit v1.2.3