From 871e9d175e07e364802f00c945cec56ef42084df Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 3 Mar 2010 09:44:44 +0000 Subject: * hash.c (rb_hash_select_bang): add #select! and keep_if to Hash. * hash.c (env_select_bang): ..and to ENV. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26803 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- hash.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'hash.c') diff --git a/hash.c b/hash.c index 51537e91b6..5eba21654e 100644 --- a/hash.c +++ b/hash.c @@ -989,6 +989,57 @@ rb_hash_select(VALUE hash) return result; } +static int +keep_if_i(VALUE key, VALUE value, VALUE hash) +{ + if (key == Qundef) return ST_CONTINUE; + if (!RTEST(rb_yield_values(2, key, value))) { + return ST_DELETE; + } + return ST_CONTINUE; +} + +/* + * call-seq: + * hsh.select! {| key, value | block } -> hsh or nil + * + * Equivalent to Hash#keep_if, but returns + * nil if no changes were made. + */ + +VALUE +rb_hash_select_bang(VALUE hash) +{ + st_index_t n; + + RETURN_ENUMERATOR(hash, 0, 0); + rb_hash_modify(hash); + if (!RHASH(hash)->ntbl) + return Qnil; + n = RHASH(hash)->ntbl->num_entries; + rb_hash_foreach(hash, keep_if_i, hash); + if (n == RHASH(hash)->ntbl->num_entries) return Qnil; + return hash; +} + +/* + * call-seq: + * hsh.keep_if {| key, value | block } -> hsh + * + * Deletes every key-value pair from hsh for which block + * evaluates to false. + * + */ + +VALUE +rb_hash_keep_if(VALUE hash) +{ + RETURN_ENUMERATOR(hash, 0, 0); + rb_hash_modify(hash); + rb_hash_foreach(hash, keep_if_i, hash); + return hash; +} + static int clear_i(VALUE key, VALUE value, VALUE dummy) { @@ -2367,6 +2418,37 @@ env_select(VALUE ehash) return result; } +static VALUE +env_select_bang(VALUE ehash) +{ + volatile VALUE keys; + long i; + int del = 0; + + RETURN_ENUMERATOR(ehash, 0, 0); + keys = env_keys(); /* rb_secure(4); */ + for (i=0; i