Skip to content
Closed
46 changes: 46 additions & 0 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -1242,6 +1242,50 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary)
return Qnil;
}


/*
* Call-seq:
*
* array.indexes(elem) -> array
*
* Returns an array of indexes of the word into the concerned array
*
* a = ["a", "b", "c", "a"]
* a.indexes("a") # => [0, 3]
* a.index_all("a") # => [0, 3]
* a.indexes("b") # => [1]
*
* This method also has an alias which is Array#index_all
*/
static VALUE
rb_ary_indexes(int argc, VALUE *argv, VALUE ary)
{

VALUE val;
long i;

if (argc > 0) {
RETURN_ENUMERATOR(ary, 0, 0);
array_length = 0;

for (i=0; i<RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
array_length++;
}
}

indexes = rb_ary_new2(array_length);
index = 0;

for (i=0; i<RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
indexes[index] = LONG2NUM(i);
index++;
}
}
return indexes;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there is no return outside this if (argc == 0) { block, a "control reaches end of non-void function" error will be generated.

This will crash ruby. You should handle argc > 0 here.

}
/*
* call-seq:
* ary.rindex(obj) -> int or nil
Expand Down Expand Up @@ -5076,6 +5120,8 @@ Init_Array(void)
rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
rb_define_method(rb_cArray, "find_index", rb_ary_index, -1);
rb_define_method(rb_cArray, "index", rb_ary_index, -1);
rb_define_method(rb_cArray, "indexes", rb_ary_indexes, -1);
rb_define_method(rb_cArray, "index_all", rb_ary_indexes, -1);
rb_define_method(rb_cArray, "rindex", rb_ary_rindex, -1);
rb_define_method(rb_cArray, "join", rb_ary_join_m, -1);
rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0);
Expand Down
7 changes: 7 additions & 0 deletions test/ruby/test_array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,13 @@ def test_index
assert_equal(1, a.index(99) {|x| x == 'cat' })
end

def test_indexes
a = @cls[ 'cat', 99, /a/, 99, @cls[ 1, 2, 3] ]
assert_equal(@cls[1, 3], a.indexes(99))
assert_equal(@cls[], a.indexes('car'))
assert_equal(@cls[4], a.indexes([1,2,3]))
end

def test_values_at
a = @cls[*('a'..'j').to_a]
assert_equal(@cls['a', 'c', 'e'], a.values_at(0, 2, 4))
Expand Down