* 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
This commit is contained in:
parent
800dda6c28
commit
871e9d175e
@ -1,3 +1,9 @@
|
|||||||
|
Wed Mar 3 18:35:55 2010 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* hash.c (rb_hash_select_bang): add #select! and keep_if to Hash.
|
||||||
|
|
||||||
|
* hash.c (env_select_bang): ..and to ENV.
|
||||||
|
|
||||||
Wed Mar 3 15:54:20 2010 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Wed Mar 3 15:54:20 2010 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* lib/matrix.rb (Vector#each2, collect2): small refactoring.
|
* lib/matrix.rb (Vector#each2, collect2): small refactoring.
|
||||||
|
86
hash.c
86
hash.c
@ -989,6 +989,57 @@ rb_hash_select(VALUE hash)
|
|||||||
return result;
|
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 <code>Hash#keep_if</code>, but returns
|
||||||
|
* <code>nil</code> 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 <i>hsh</i> for which <i>block</i>
|
||||||
|
* evaluates to <code>false</code>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
clear_i(VALUE key, VALUE value, VALUE dummy)
|
clear_i(VALUE key, VALUE value, VALUE dummy)
|
||||||
{
|
{
|
||||||
@ -2367,6 +2418,37 @@ env_select(VALUE ehash)
|
|||||||
return result;
|
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<RARRAY_LEN(keys); i++) {
|
||||||
|
VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
|
||||||
|
if (!NIL_P(val)) {
|
||||||
|
if (!RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
|
||||||
|
FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
|
||||||
|
env_delete(Qnil, RARRAY_PTR(keys)[i]);
|
||||||
|
del++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (del == 0) return Qnil;
|
||||||
|
return envtbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
env_keep_if(VALUE ehash)
|
||||||
|
{
|
||||||
|
RETURN_ENUMERATOR(ehash, 0, 0);
|
||||||
|
env_select_bang(ehash);
|
||||||
|
return envtbl;
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_env_clear(void)
|
rb_env_clear(void)
|
||||||
{
|
{
|
||||||
@ -2755,7 +2837,9 @@ Init_Hash(void)
|
|||||||
rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
|
rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
|
||||||
rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
|
rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
|
||||||
rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
|
rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
|
||||||
|
rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0);
|
||||||
rb_define_method(rb_cHash,"select", rb_hash_select, 0);
|
rb_define_method(rb_cHash,"select", rb_hash_select, 0);
|
||||||
|
rb_define_method(rb_cHash,"select!", rb_hash_select_bang, 0);
|
||||||
rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
|
rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
|
||||||
rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
|
rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
|
||||||
rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
|
rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
|
||||||
@ -2792,10 +2876,12 @@ Init_Hash(void)
|
|||||||
rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
|
rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
|
||||||
rb_define_singleton_method(envtbl,"delete", env_delete_m, 1);
|
rb_define_singleton_method(envtbl,"delete", env_delete_m, 1);
|
||||||
rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
|
rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
|
||||||
|
rb_define_singleton_method(envtbl,"keep_if", env_keep_if, 0);
|
||||||
rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0);
|
rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0);
|
||||||
rb_define_singleton_method(envtbl,"reject", env_reject, 0);
|
rb_define_singleton_method(envtbl,"reject", env_reject, 0);
|
||||||
rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
|
rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
|
||||||
rb_define_singleton_method(envtbl,"select", env_select, 0);
|
rb_define_singleton_method(envtbl,"select", env_select, 0);
|
||||||
|
rb_define_singleton_method(envtbl,"select!", env_select_bang, 0);
|
||||||
rb_define_singleton_method(envtbl,"shift", env_shift, 0);
|
rb_define_singleton_method(envtbl,"shift", env_shift, 0);
|
||||||
rb_define_singleton_method(envtbl,"invert", env_invert, 0);
|
rb_define_singleton_method(envtbl,"invert", env_invert, 0);
|
||||||
rb_define_singleton_method(envtbl,"replace", env_replace, 1);
|
rb_define_singleton_method(envtbl,"replace", env_replace, 1);
|
||||||
|
@ -290,6 +290,13 @@ class TestHash < Test::Unit::TestCase
|
|||||||
assert_equal(base.size, n)
|
assert_equal(base.size, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_delete_if
|
||||||
|
h = {1=>2,3=>4,5=>6}
|
||||||
|
assert_equal({3=>4,5=>6}, h.keep_if {|k, v| k + v >= 7 })
|
||||||
|
h = {1=>2,3=>4,5=>6}
|
||||||
|
assert_equal({1=>2,3=>4,5=>6}, h.keep_if{true})
|
||||||
|
end
|
||||||
|
|
||||||
def test_dup
|
def test_dup
|
||||||
for taint in [ false, true ]
|
for taint in [ false, true ]
|
||||||
for untrust in [ false, true ]
|
for untrust in [ false, true ]
|
||||||
@ -736,6 +743,14 @@ class TestHash < Test::Unit::TestCase
|
|||||||
assert_equal({3=>4,5=>6}, {1=>2,3=>4,5=>6}.select {|k, v| k + v >= 7 })
|
assert_equal({3=>4,5=>6}, {1=>2,3=>4,5=>6}.select {|k, v| k + v >= 7 })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_select!
|
||||||
|
h = {1=>2,3=>4,5=>6}
|
||||||
|
assert_equal(h, h.select! {|k, v| k + v >= 7 })
|
||||||
|
assert_equal({3=>4,5=>6}, h)
|
||||||
|
h = {1=>2,3=>4,5=>6}
|
||||||
|
assert_equal(nil, h.select!{true})
|
||||||
|
end
|
||||||
|
|
||||||
def test_clear2
|
def test_clear2
|
||||||
assert_equal({}, {1=>2,3=>4,5=>6}.clear)
|
assert_equal({}, {1=>2,3=>4,5=>6}.clear)
|
||||||
h = {1=>2,3=>4,5=>6}
|
h = {1=>2,3=>4,5=>6}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user