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:
parent
35345f1c09
commit
006a8ba77f
3 changed files with 76 additions and 0 deletions
|
@ -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
53
array.c
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue