1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* array.c (rb_ary_select_bang): select! removes all elements for

which block returns false.  [ruby-core:27286]

* array.c (rb_ary_keep_if): #keep_if, new method.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26800 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2010-03-03 05:35:08 +00:00
parent 35345f1c09
commit 006a8ba77f
3 changed files with 76 additions and 0 deletions

View file

@ -1,3 +1,10 @@
Wed Mar 3 14:28:23 2010 Yukihiro Matsumoto <matz@ruby-lang.org>
* array.c (rb_ary_select_bang): select! removes all elements for
which block returns false. [ruby-core:27286]
* array.c (rb_ary_keep_if): #keep_if, new method.
Wed Mar 3 06:19:25 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* win32/win32.c (signbig): defined.

53
array.c
View file

@ -2248,6 +2248,57 @@ rb_ary_select(VALUE ary)
return result;
}
/*
* call-seq:
* array.select! {|item| block } -> an_array
*
* Invokes the block passing in successive elements from
* <i>array</i>, deleting elements for which the block returns a
* false value. but returns <code>nil</code> if no changes were
* made. Also see <code>Array#keep_if</code>
*/
static VALUE
rb_ary_select_bang(VALUE ary)
{
long i1, i2;
RETURN_ENUMERATOR(ary, 0, 0);
rb_ary_modify(ary);
for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
VALUE v = RARRAY_PTR(ary)[i1];
if (!RTEST(rb_yield(v))) continue;
if (i1 != i2) {
rb_ary_store(ary, i2, v);
}
i2++;
}
if (RARRAY_LEN(ary) == i2) return Qnil;
if (i2 < RARRAY_LEN(ary))
ARY_SET_LEN(ary, i2);
return ary;
}
/*
* call-seq:
* array.keep_if {|item| block } -> an_array
*
* Deletes every element of <i>self</i> for which <i>block</i> evaluates
* to <code>false</code>.
*
* a = %w{ a b c d e f }
* a.keep_if {|v| v =~ /[aeiou]/} #=> ["a", "e"]
*/
static VALUE
rb_ary_keep_if(VALUE ary)
{
RETURN_ENUMERATOR(ary, 0, 0);
rb_ary_select_bang(ary);
return ary;
}
/*
* call-seq:
* array.delete(obj) -> obj or nil
@ -4239,6 +4290,8 @@ Init_Array(void)
rb_define_method(rb_cArray, "map", rb_ary_collect, 0);
rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0);
rb_define_method(rb_cArray, "select", rb_ary_select, 0);
rb_define_method(rb_cArray, "select!", rb_ary_select_bang, 0);
rb_define_method(rb_cArray, "keep_if", rb_ary_keep_if, 0);
rb_define_method(rb_cArray, "values_at", rb_ary_values_at, -1);
rb_define_method(rb_cArray, "delete", rb_ary_delete, 1);
rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1);

View file

@ -1590,6 +1590,22 @@ class TestArray < Test::Unit::TestCase
assert_equal([0, 2], [0, 1, 2, 3].select {|x| x % 2 == 0 })
end
# also keep_if
def test_select!
a = @cls[ 1, 2, 3, 4, 5 ]
assert_equal(nil, a.select! { true })
assert_equal(a, a.keep_if { true })
assert_equal(@cls[1, 2, 3, 4, 5], a)
a = @cls[ 1, 2, 3, 4, 5 ]
assert_equal(a, a.select! { false })
assert_equal(@cls[], a)
a = @cls[ 1, 2, 3, 4, 5 ]
assert_equal(a, a.select! { |i| i > 3 })
assert_equal(@cls[4, 5], a)
end
def test_delete2
a = [0] * 1024 + [1] + [0] * 1024
a.delete(0)