class Array

An Array object is an ordered, integer-indexed collection of objects, calledelements; the object represents anarray data structure.

An element may be any object (even another array); elements may be any mixture of objects of different types.

Important data structures that use arrays include:

There are also array-like data structures:

Array Indexes

Array indexing starts at 0, as in C or Java.

A non-negative index is an offset from the first element:

A negative index is an offset, backwards, from the end of the array:

In-Range and Out-of-Range Indexes

A non-negative index isin range if and only if it is smaller than the size of the array. For a 3-element array:

A negative index isin range if and only if its absolute value is not larger than the size of the array. For a 3-element array:

Effective Index

Although the effective index into an array is always an integer, some methods (both within class Array and elsewhere) accept one or more non-integer arguments that areinteger-convertible objects.

Creating Arrays

You can create an Array object explicitly with:

A number of Ruby methods, both in the core and in the standard library, provide instance methodto_a, which converts an object to an array.

Example Usage

In addition to the methods it mixes in through theEnumerable module, class Array has proprietary methods for accessing, searching and otherwise manipulating arrays.

Some of the more common ones are illustrated below.

Accessing Elements

Elements in an array can be retrieved using theArray#[] method. It can take a single integer argument (a numeric index), a pair of arguments (start and length) or a range. Negative indices start counting from the end, with -1 being the last element.

arr = [1,2,3,4,5,6]arr[2]#=> 3arr[100]#=> nilarr[-3]#=> 4arr[2,3]#=> [3, 4, 5]arr[1..4]#=> [2, 3, 4, 5]arr[1..-3]#=> [2, 3, 4]

Another way to access a particular array element is by using theat method

arr.at(0)#=> 1

Theslice method works in an identical manner toArray#[].

To raise an error for indices outside of the array bounds or else to provide a default value when that happens, you can usefetch.

arr = ['a','b','c','d','e','f']arr.fetch(100)#=> IndexError: index 100 outside of array bounds: -6...6arr.fetch(100,"oops")#=> "oops"

The special methodsfirst andlast will return the first and last elements of an array, respectively.

arr.first#=> 1arr.last#=> 6

To return the firstn elements of an array, usetake

arr.take(3)#=> [1, 2, 3]

drop does the opposite oftake, by returning the elements aftern elements have been dropped:

arr.drop(3)#=> [4, 5, 6]

Obtaining Information about an Array

An array keeps track of its own length at all times. To query an array about the number of elements it contains, uselength,count orsize.

browsers = ['Chrome','Firefox','Safari','Opera','IE']browsers.length#=> 5browsers.count#=> 5

To check whether an array contains any elements at all

browsers.empty?#=> false

To check whether a particular item is included in the array

browsers.include?('Konqueror')#=> false

Adding Items to an Array

Items can be added to the end of an array by using eitherpush or<<

arr = [1,2,3,4]arr.push(5)#=> [1, 2, 3, 4, 5]arr<<6#=> [1, 2, 3, 4, 5, 6]

unshift will add a new item to the beginning of an array.

arr.unshift(0)#=> [0, 1, 2, 3, 4, 5, 6]

Withinsert you can add a new element to an array at any position.

arr.insert(3,'apple')#=> [0, 1, 2, 'apple', 3, 4, 5, 6]

Using theinsert method, you can also insert multiple values at once:

arr.insert(3,'orange','pear','grapefruit')#=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]

Removing Items from an Array

The methodpop removes the last element in an array and returns it:

arr =  [1,2,3,4,5,6]arr.pop#=> 6arr#=> [1, 2, 3, 4, 5]

To retrieve and at the same time remove the first item, useshift:

arr.shift#=> 1arr#=> [2, 3, 4, 5]

To delete an element at a particular index:

arr.delete_at(2)#=> 4arr#=> [2, 3, 5]

To delete a particular element anywhere in an array, usedelete:

arr = [1,2,2,3]arr.delete(2)#=> 2arr#=> [1,3]

A useful method if you need to removenil values from an array iscompact:

arr = ['foo',0,nil,'bar',7,'baz',nil]arr.compact#=> ['foo', 0, 'bar', 7, 'baz']arr#=> ['foo', 0, nil, 'bar', 7, 'baz', nil]arr.compact!#=> ['foo', 0, 'bar', 7, 'baz']arr#=> ['foo', 0, 'bar', 7, 'baz']

Another common need is to remove duplicate elements from an array.

It has the non-destructiveuniq, and destructive methoduniq!

arr = [2,5,6,556,6,6,8,9,0,123,556]arr.uniq#=> [2, 5, 6, 556, 8, 9, 0, 123]

Iterating over an Array

Like all classes that include theEnumerable module, class Array has an each method, which defines what elements should be iterated over and how. In case ofArray#each, all elements inself are yielded to the supplied block in sequence.

Note that this operation leaves the array unchanged.

arr = [1,2,3,4,5]arr.each {|a|printa-=10," "}# prints: -9 -8 -7 -6 -5#=> [1, 2, 3, 4, 5]

Another sometimes useful iterator isreverse_each which will iterate over the elements in the array in reverse order.

words =%w[first second third fourth fifth sixth]str =""words.reverse_each {|word|str+="#{word} "}pstr#=> "sixth fifth fourth third second first "

Themap method can be used to create a new array based on the original array, but with the values modified by the supplied block:

arr.map {|a|2*a}#=> [2, 4, 6, 8, 10]arr#=> [1, 2, 3, 4, 5]arr.map! {|a|a**2}#=> [1, 4, 9, 16, 25]arr#=> [1, 4, 9, 16, 25]

Selecting Items from an Array

Elements can be selected from an array according to criteria defined in a block. The selection can happen in a destructive or a non-destructive manner. While the destructive operations will modify the array they were called on, the non-destructive methods usually return a new array with the selected elements, but leave the original array unchanged.

Non-destructive Selection

arr = [1,2,3,4,5,6]arr.select {|a|a>3}#=> [4, 5, 6]arr.reject {|a|a<3}#=> [3, 4, 5, 6]arr.drop_while {|a|a<4}#=> [4, 5, 6]arr#=> [1, 2, 3, 4, 5, 6]

Destructive Selection

select! andreject! are the corresponding destructive methods toselect andreject

Similar toselect vs.reject,delete_if andkeep_if have the exact opposite result when supplied with the same block:

arr.delete_if {|a|a<4}#=> [4, 5, 6]arr#=> [4, 5, 6]arr = [1,2,3,4,5,6]arr.keep_if {|a|a<4}#=> [1, 2, 3]arr#=> [1, 2, 3]

What’s Here

First, what’s elsewhere. Class Array:

Here, class Array provides methods that are useful for:

Methods for Creating an Array

See alsoCreating Arrays.

Methods for Querying

Methods for Comparing

Methods for Fetching

These methods do not modifyself.

Methods for Assigning

These methods add, replace, or reorder elements inself.

Methods for Deleting

Each of these methods removes elements fromself:

Methods for Combining

Methods for Iterating

Methods for Converting

Other Methods

Public Class Methods

Source
static VALUErb_ary_s_create(int argc, VALUE *argv, VALUE klass){    VALUE ary = ary_new(klass, argc);    if (argc > 0 && argv) {        ary_memcpy(ary, 0, argc, argv);        ARY_SET_LEN(ary, argc);    }    return ary;}

Returns a new array, populated with the given objects:

Array[1,'a',/^A/]# => [1, "a", /^A/]Array[]# => []Array.[](1,'a',/^A/)# => [1, "a", /^A/]

Related: seeMethods for Creating an Array.

Source
static VALUErb_ary_initialize(int argc, VALUE *argv, VALUE ary){    long len;    VALUE size, val;    rb_ary_modify(ary);    if (argc == 0) {        rb_ary_reset(ary);        RUBY_ASSERT(ARY_EMBED_P(ary));        RUBY_ASSERT(ARY_EMBED_LEN(ary) == 0);        if (rb_block_given_p()) {            rb_warning("given block not used");        }        return ary;    }    rb_scan_args(argc, argv, "02", &size, &val);    if (argc == 1 && !FIXNUM_P(size)) {        val = rb_check_array_type(size);        if (!NIL_P(val)) {            rb_ary_replace(ary, val);            return ary;        }    }    len = NUM2LONG(size);    /* NUM2LONG() may call size.to_int, ary can be frozen, modified, etc */    if (len < 0) {        rb_raise(rb_eArgError, "negative array size");    }    if (len > ARY_MAX_SIZE) {        rb_raise(rb_eArgError, "array size too big");    }    /* recheck after argument conversion */    rb_ary_modify(ary);    ary_resize_capa(ary, len);    if (rb_block_given_p()) {        long i;        if (argc == 2) {            rb_warn("block supersedes default value argument");        }        for (i=0; i<len; i++) {            rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));            ARY_SET_LEN(ary, i + 1);        }    }    else {        ary_memfill(ary, 0, len, val);        ARY_SET_LEN(ary, len);    }    return ary;}

Returns a new array.

With no block and no argument given, returns a new empty array:

Array.new# => []

With no block and array argument given, returns a new array with the same elements:

Array.new([:foo,'bar',2])# => [:foo, "bar", 2]

With no block and integer argument given, returns a new array containing that many instances of the givendefault_value:

Array.new(0)# => []Array.new(3)# => [nil, nil, nil]Array.new(2,3)# => [3, 3]

With a block given, returns an array of the givensize; calls the block with eachindex in the range(0...size); the element at thatindex in the returned array is the blocks return value:

Array.new(3)  {|index|"Element #{index}" }# => ["Element 0", "Element 1", "Element 2"]

A common pitfall for new Rubyists is providing an expression asdefault_value:

array =Array.new(2, {})array# => [{}, {}]array[0][:a] =1array# => [{a: 1}, {a: 1}], as array[0] and array[1] are same object

If you want the elements of the array to be distinct, you should pass a block:

array =Array.new(2) { {} }array# => [{}, {}]array[0][:a] =1array# => [{a: 1}, {}], as array[0] and array[1] are different objects

RaisesTypeError if the first argument is not either an array or aninteger-convertible object). RaisesArgumentError if the first argument is a negative integer.

Related: seeMethods for Creating an Array.

Source
static VALUErb_ary_s_try_convert(VALUE dummy, VALUE ary){    return rb_check_array_type(ary);}

Attempts to return an array, based on the givenobject.

Ifobject is an array, returnsobject.

Otherwise ifobject responds to:to_ary. callsobject.to_ary: if the return value is an array ornil, returns that value; if not, raisesTypeError.

Otherwise returnsnil.

Related: seeMethods for Creating an Array.

Public Instance Methods

Source
static VALUErb_ary_and(VALUE ary1, VALUE ary2){    VALUE hash, ary3, v;    st_data_t vv;    long i;    ary2 = to_ary(ary2);    ary3 = rb_ary_new();    if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3;    if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {        for (i=0; i<RARRAY_LEN(ary1); i++) {            v = RARRAY_AREF(ary1, i);            if (!rb_ary_includes_by_eql(ary2, v)) continue;            if (rb_ary_includes_by_eql(ary3, v)) continue;            rb_ary_push(ary3, v);        }        return ary3;    }    hash = ary_make_hash(ary2);    for (i=0; i<RARRAY_LEN(ary1); i++) {        v = RARRAY_AREF(ary1, i);        vv = (st_data_t)v;        if (rb_hash_stlike_delete(hash, &vv, 0)) {            rb_ary_push(ary3, v);        }    }    return ary3;}

Returns a new array containing theintersection ofself andother_array; that is, containing those elements found in bothself andother_array:

[0,1,2,3]& [1,2]# => [1, 2]

Omits duplicates:

[0,1,1,0]& [0,1]# => [0, 1]

Preserves order fromself:

[0,1,2]& [3,2,1,0]# => [0, 1, 2]

Identifies common elements using methodeql? (as defined in each element ofself).

Related: seeMethods for Combining.

Source
static VALUErb_ary_times(VALUE ary, VALUE times){    VALUE ary2, tmp;    const VALUE *ptr;    long t, len;    tmp = rb_check_string_type(times);    if (!NIL_P(tmp)) {        return rb_ary_join(ary, tmp);    }    len = NUM2LONG(times);    if (len == 0) {        ary2 = ary_new(rb_cArray, 0);        goto out;    }    if (len < 0) {        rb_raise(rb_eArgError, "negative argument");    }    if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {        rb_raise(rb_eArgError, "argument too big");    }    len *= RARRAY_LEN(ary);    ary2 = ary_new(rb_cArray, len);    ARY_SET_LEN(ary2, len);    ptr = RARRAY_CONST_PTR(ary);    t = RARRAY_LEN(ary);    if (0 < t) {        ary_memcpy(ary2, 0, t, ptr);        while (t <= len/2) {            ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));            t *= 2;        }        if (t < len) {            ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));        }    }  out:    return ary2;}

When non-negative integer argumentn is given, returns a new array built by concatenatingn copies ofself:

a = ['x','y']a*3# => ["x", "y", "x", "y", "x", "y"]

When string argumentstring_separator is given, equivalent toself.join(string_separator):

[0, [0,1], {foo:0}]*', '# => "0, 0, 1, {foo: 0}"
Source
VALUErb_ary_plus(VALUE x, VALUE y){    VALUE z;    long len, xlen, ylen;    y = to_ary(y);    xlen = RARRAY_LEN(x);    ylen = RARRAY_LEN(y);    len = xlen + ylen;    z = rb_ary_new2(len);    ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x));    ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));    ARY_SET_LEN(z, len);    return z;}

Returns a new array containing all elements ofself followed by all elements ofother_array:

a = [0,1]+ [2,3]a# => [0, 1, 2, 3]

Related: seeMethods for Combining.

Source
VALUErb_ary_diff(VALUE ary1, VALUE ary2){    VALUE ary3;    VALUE hash;    long i;    ary2 = to_ary(ary2);    if (RARRAY_LEN(ary2) == 0) { return ary_make_shared_copy(ary1); }    ary3 = rb_ary_new();    if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {        for (i=0; i<RARRAY_LEN(ary1); i++) {            VALUE elt = rb_ary_elt(ary1, i);            if (rb_ary_includes_by_eql(ary2, elt)) continue;            rb_ary_push(ary3, elt);        }        return ary3;    }    hash = ary_make_hash(ary2);    for (i=0; i<RARRAY_LEN(ary1); i++) {        if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;        rb_ary_push(ary3, rb_ary_elt(ary1, i));    }    return ary3;}

Returns a new array containing only those elements ofself that are not found inother_array; the order fromself is preserved:

[0,1,1,2,1,1,3,1,1]- [1]# => [0, 2, 3][0,1,1,2,1,1,3,1,1]- [3,2,0,:foo]# => [1, 1, 1, 1, 1, 1][0,1,2]- [:foo]# => [0, 1, 2]

Element are compared using methodeql? (as defined in each element ofself).

Related: seeMethods for Combining.

Source
VALUErb_ary_push(VALUE ary, VALUE item){    long idx = RARRAY_LEN((ary_verify(ary), ary));    VALUE target_ary = ary_ensure_room_for_push(ary, 1);    RARRAY_PTR_USE(ary, ptr, {        RB_OBJ_WRITE(target_ary, &ptr[idx], item);    });    ARY_SET_LEN(ary, idx + 1);    ary_verify(ary);    return ary;}

Appendsobject as the last element inself; returnsself:

[:foo,'bar',2]<<:baz# => [:foo, "bar", 2, :baz]

Appendsobject as a single element, even if it is another array:

[:foo,'bar',2]<< [3,4]# => [:foo, "bar", 2, [3, 4]]

Related: seeMethods for Assigning.

Source
VALUErb_ary_cmp(VALUE ary1, VALUE ary2){    long len;    VALUE v;    ary2 = rb_check_array_type(ary2);    if (NIL_P(ary2)) return Qnil;    if (ary1 == ary2) return INT2FIX(0);    v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);    if (!UNDEF_P(v)) return v;    len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);    if (len == 0) return INT2FIX(0);    if (len > 0) return INT2FIX(1);    return INT2FIX(-1);}

Returns -1, 0, or 1 asself is determined to be less than, equal to, or greater thanother_array.

Iterates over each indexi in(0...self.size):

  • Computesresult[i] asself[i] <=> other_array[i].

  • Immediately returns 1 ifresult[i] is 1:

    [0,1,2]<=> [0,0,2]# => 1
  • Immediately returns -1 ifresult[i] is -1:

    [0,1,2]<=> [0,2,2]# => -1
  • Continues ifresult[i] is 0.

When everyresult is 0, returnsself.size <=> other_array.size (seeInteger#<=>):

[0,1,2]<=> [0,1]# => 1[0,1,2]<=> [0,1,2]# => 0[0,1,2]<=> [0,1,2,3]# => -1

Note that whenother_array is larger thanself, its trailing elements do not affect the result:

[0,1,2]<=> [0,1,2,-3]# => -1[0,1,2]<=> [0,1,2,0]# => -1[0,1,2]<=> [0,1,2,3]# => -1

Related: seeMethods for Comparing.

Source
static VALUErb_ary_equal(VALUE ary1, VALUE ary2){    if (ary1 == ary2) return Qtrue;    if (!RB_TYPE_P(ary2, T_ARRAY)) {        if (!rb_respond_to(ary2, idTo_ary)) {            return Qfalse;        }        return rb_equal(ary2, ary1);    }    if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;    if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;    return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);}

Returns whether both:

  • self andother_array are the same size.

  • Their corresponding elements are the same; that is, for each indexi in(0...self.size),self[i] == other_array[i].

Examples:

[:foo,'bar',2]== [:foo,'bar',2]# => true[:foo,'bar',2]== [:foo,'bar',2.0]# => true[:foo,'bar',2]== [:foo,'bar']# => false # Different sizes.[:foo,'bar',2]== [:foo,'bar',3]# => false # Different elements.

This method is different from methodArray#eql?, which compares elements usingObject#eql?.

Related: seeMethods for Comparing.

Source
VALUErb_ary_aref(int argc, const VALUE *argv, VALUE ary){    rb_check_arity(argc, 1, 2);    if (argc == 2) {        return rb_ary_aref2(ary, argv[0], argv[1]);    }    return rb_ary_aref1(ary, argv[0]);}

Returns elements fromself; does not modifyself.

In brief:

a = [:foo,'bar',2]# Single argument index: returns one element.a[0]# => :foo          # Zero-based index.a[-1]# => 2             # Negative index counts backwards from end.# Arguments start and length: returns an array.a[1,2]# => ["bar", 2]a[-2,2]# => ["bar", 2]    # Negative start counts backwards from end.# Single argument range: returns an array.a[0..1]# => [:foo, "bar"]a[0..-2]# => [:foo, "bar"] # Negative range-begin counts backwards from end.a[-2..2]# => ["bar", 2]    # Negative range-end counts backwards from end.

When a single integer argumentindex is given, returns the element at offsetindex:

a = [:foo,'bar',2]a[0]# => :fooa[2]# => 2a# => [:foo, "bar", 2]

Ifindex is negative, counts backwards from the end ofself:

a = [:foo,'bar',2]a[-1]# => 2a[-2]# => "bar"

Ifindex is out of range, returnsnil.

When twoInteger argumentsstart andlength are given, returns a new array of sizelength containing successive elements beginning at offsetstart:

a = [:foo,'bar',2]a[0,2]# => [:foo, "bar"]a[1,2]# => ["bar", 2]

Ifstart + length is greater thanself.length, returns all elements from offsetstart to the end:

a = [:foo,'bar',2]a[0,4]# => [:foo, "bar", 2]a[1,3]# => ["bar", 2]a[2,2]# => [2]

Ifstart == self.size andlength >= 0, returns a new empty array.

Iflength is negative, returnsnil.

When a singleRange argumentrange is given, treatsrange.min asstart above andrange.size aslength above:

a = [:foo,'bar',2]a[0..1]# => [:foo, "bar"]a[1..2]# => ["bar", 2]

Special case: Ifrange.start == a.size, returns a new empty array.

Ifrange.end is negative, calculates the end index from the end:

a = [:foo,'bar',2]a[0..-1]# => [:foo, "bar", 2]a[0..-2]# => [:foo, "bar"]a[0..-3]# => [:foo]

Ifrange.start is negative, calculates the start index from the end:

a = [:foo,'bar',2]a[-1..2]# => [2]a[-2..2]# => ["bar", 2]a[-3..2]# => [:foo, "bar", 2]

Ifrange.start is larger than the array size, returnsnil.

a = [:foo,'bar',2]a[4..1]# => nila[4..0]# => nila[4..-1]# => nil

When a singleEnumerator::ArithmeticSequence argumentaseq is given, returns an array of elements corresponding to the indexes produced by the sequence.

a = ['--','data1','--','data2','--','data3']a[(1..).step(2)]# => ["data1", "data2", "data3"]

Unlike slicing with range, if the start or the end of the arithmetic sequence is larger than array size, throwsRangeError.

a = ['--','data1','--','data2','--','data3']a[(1..11).step(2)]# RangeError (((1..11).step(2)) out of range)a[(7..).step(2)]# RangeError (((7..).step(2)) out of range)

If given a single argument, and its type is not one of the listed, tries to convert it toInteger, and raises if it is impossible:

a = [:foo,'bar',2]# Raises TypeError (no implicit conversion of Symbol into Integer):a[:foo]

Related: seeMethods for Fetching.

Also aliased as:slice
Source
static VALUErb_ary_aset(int argc, VALUE *argv, VALUE ary){    long offset, beg, len;    rb_check_arity(argc, 2, 3);    rb_ary_modify_check(ary);    if (argc == 3) {        beg = NUM2LONG(argv[0]);        len = NUM2LONG(argv[1]);        return ary_aset_by_rb_ary_splice(ary, beg, len, argv[2]);    }    if (FIXNUM_P(argv[0])) {        offset = FIX2LONG(argv[0]);        return ary_aset_by_rb_ary_store(ary, offset, argv[1]);    }    if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {        /* check if idx is Range */        return ary_aset_by_rb_ary_splice(ary, beg, len, argv[1]);    }    offset = NUM2LONG(argv[0]);    return ary_aset_by_rb_ary_store(ary, offset, argv[1]);}

Assigns elements inself, based on the givenobject; returnsobject.

In brief:

a_orig = [:foo,'bar',2]# With argument index.a =a_orig.dupa[0] ='foo'# => "foo"a# => ["foo", "bar", 2]a =a_orig.dupa[7] ='foo'# => "foo"a# => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]# With arguments start and length.a =a_orig.dupa[0,2] ='foo'# => "foo"a# => ["foo", 2]a =a_orig.dupa[6,50] ='foo'# => "foo"a# => [:foo, "bar", 2, nil, nil, nil, "foo"]# With argument range.a =a_orig.dupa[0..1] ='foo'# => "foo"a# => ["foo", 2]a =a_orig.dupa[6..50] ='foo'# => "foo"a# => [:foo, "bar", 2, nil, nil, nil, "foo"]

WhenInteger argumentindex is given, assignsobject to an element inself.

Ifindex is non-negative, assignsobject the element at offsetindex:

a = [:foo,'bar',2]a[0] ='foo'# => "foo"a# => ["foo", "bar", 2]

Ifindex is greater thanself.length, extends the array:

a = [:foo,'bar',2]a[7] ='foo'# => "foo"a# => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]

Ifindex is negative, counts backwards from the end of the array:

a = [:foo,'bar',2]a[-1] ='two'# => "two"a# => [:foo, "bar", "two"]

WhenInteger argumentsstart andlength are given andobject is not an array, removeslength - 1 elements beginning at offsetstart, and assignsobject at offsetstart:

a = [:foo,'bar',2]a[0,2] ='foo'# => "foo"a# => ["foo", 2]

Ifstart is negative, counts backwards from the end of the array:

a = [:foo,'bar',2]a[-2,2] ='foo'# => "foo"a# => [:foo, "foo"]

Ifstart is non-negative and outside the array ( >= self.size), extends the array withnil, assignsobject at offsetstart, and ignoreslength:

a = [:foo,'bar',2]a[6,50] ='foo'# => "foo"a# => [:foo, "bar", 2, nil, nil, nil, "foo"]

Iflength is zero, shifts elements at and following offsetstart and assignsobject at offsetstart:

a = [:foo,'bar',2]a[1,0] ='foo'# => "foo"a# => [:foo, "foo", "bar", 2]

Iflength is too large for the existing array, does not extend the array:

a = [:foo,'bar',2]a[1,5] ='foo'# => "foo"a# => [:foo, "foo"]

WhenRange argumentrange is given andobject is not an array, removeslength - 1 elements beginning at offsetstart, and assignsobject at offsetstart:

a = [:foo,'bar',2]a[0..1] ='foo'# => "foo"a# => ["foo", 2]

ifrange.begin is negative, counts backwards from the end of the array:

a = [:foo,'bar',2]a[-2..2] ='foo'# => "foo"a# => [:foo, "foo"]

If the array length is less thanrange.begin, extends the array withnil, assignsobject at offsetrange.begin, and ignoreslength:

a = [:foo,'bar',2]a[6..50] ='foo'# => "foo"a# => [:foo, "bar", 2, nil, nil, nil, "foo"]

Ifrange.end is zero, shifts elements at and following offsetstart and assignsobject at offsetstart:

a = [:foo,'bar',2]a[1..0] ='foo'# => "foo"a# => [:foo, "foo", "bar", 2]

Ifrange.end is negative, assignsobject at offsetstart, retainsrange.end.abs -1 elements past that, and removes those beyond:

a = [:foo,'bar',2]a[1..-1] ='foo'# => "foo"a# => [:foo, "foo"]a = [:foo,'bar',2]a[1..-2] ='foo'# => "foo"a# => [:foo, "foo", 2]a = [:foo,'bar',2]a[1..-3] ='foo'# => "foo"a# => [:foo, "foo", "bar", 2]a = [:foo,'bar',2]

Ifrange.end is too large for the existing array, replaces array elements, but does not extend the array withnil values:

a = [:foo,'bar',2]a[1..5] ='foo'# => "foo"a# => [:foo, "foo"]

Related: seeMethods for Assigning.

Source
static VALUErb_ary_or(VALUE ary1, VALUE ary2){    VALUE hash;    ary2 = to_ary(ary2);    if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {        VALUE ary3 = rb_ary_new();        rb_ary_union(ary3, ary1);        rb_ary_union(ary3, ary2);        return ary3;    }    hash = ary_make_hash(ary1);    rb_ary_union_hash(hash, ary2);    return rb_hash_values(hash);}

Returns the union ofself andother_array; duplicates are removed; order is preserved; items are compared usingeql?:

[0,1]| [2,3]# => [0, 1, 2, 3][0,1,1]| [2,2,3]# => [0, 1, 2, 3][0,1,2]| [3,2,1,0]# => [0, 1, 2, 3]

Related: seeMethods for Combining.

Source
static VALUErb_ary_all_p(int argc, VALUE *argv, VALUE ary){    long i, len = RARRAY_LEN(ary);    rb_check_arity(argc, 0, 1);    if (!len) return Qtrue;    if (argc) {        if (rb_block_given_p()) {            rb_warn("given block not used");        }        for (i = 0; i < RARRAY_LEN(ary); ++i) {            if (!RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;        }    }    else if (!rb_block_given_p()) {        for (i = 0; i < len; ++i) {            if (!RTEST(RARRAY_AREF(ary, i))) return Qfalse;        }    }    else {        for (i = 0; i < RARRAY_LEN(ary); ++i) {            if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;        }    }    return Qtrue;}

Returns whether for every element ofself, a given criterion is satisfied.

With no block and no argument, returns whether every element ofself is truthy:

[[], {},'',0,0.0,Object.new].all?# => true  # All truthy objects.[[], {},'',0,0.0,nil].all?# => false # nil is not truthy.[[], {},'',0,0.0,false].all?# => false # false is not truthy.

With argumentobject given, returns whetherobject === ele for every elementele inself:

[0,0,0].all?(0)# => true[0,1,2].all?(1)# => false['food','fool','foot'].all?(/foo/)# => true['food','drink'].all?(/foo/)# => false

With a block given, calls the block with each element inself; returns whether the block returns only truthy values:

[0,1,2].all? {|ele|ele<3 }# => true[0,1,2].all? {|ele|ele<2 }# => false

With both a block and argumentobject given, ignores the block and usesobject as above.

Special case: returnstrue ifself is empty (regardless of any given argument or block).

Related: seeMethods for Querying.

Source
static VALUErb_ary_any_p(int argc, VALUE *argv, VALUE ary){    long i, len = RARRAY_LEN(ary);    rb_check_arity(argc, 0, 1);    if (!len) return Qfalse;    if (argc) {        if (rb_block_given_p()) {            rb_warn("given block not used");        }        for (i = 0; i < RARRAY_LEN(ary); ++i) {            if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;        }    }    else if (!rb_block_given_p()) {        for (i = 0; i < len; ++i) {            if (RTEST(RARRAY_AREF(ary, i))) return Qtrue;        }    }    else {        for (i = 0; i < RARRAY_LEN(ary); ++i) {            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;        }    }    return Qfalse;}

Returns whether for any element ofself, a given criterion is satisfied.

With no block and no argument, returns whether any element ofself is truthy:

[nil,false, []].any?# => true  # Array object is truthy.[nil,false, {}].any?# => true  # Hash object is truthy.[nil,false,''].any?# => true  # String object is truthy.[nil,false].any?# => false # Nil and false are not truthy.

With argumentobject given, returns whetherobject === ele for any elementele inself:

[nil,false,0].any?(0)# => true[nil,false,1].any?(0)# => false[nil,false,'food'].any?(/foo/)# => true[nil,false,'food'].any?(/bar/)# => false

With a block given, calls the block with each element inself; returns whether the block returns any truthy value:

[0,1,2].any? {|ele|ele<1 }# => true[0,1,2].any? {|ele|ele<0 }# => false

With both a block and argumentobject given, ignores the block and usesobject as above.

Special case: returnsfalse ifself is empty (regardless of any given argument or block).

Related: seeMethods for Querying.

Appends each argument inobjects toself; returnsself:

a = [:foo,'bar',2]# => [:foo, "bar", 2]a.push(:baz,:bat)# => [:foo, "bar", 2, :baz, :bat]

Appends each argument as a single element, even if it is another array:

a = [:foo,'bar',2]# => [:foo, "bar", 2]a.push([:baz,:bat], [:bam,:bad])# => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]

Related: seeMethods for Assigning.

Alias for:push
Source
VALUErb_ary_assoc(VALUE ary, VALUE key){    long i;    VALUE v;    for (i = 0; i < RARRAY_LEN(ary); ++i) {        v = rb_check_array_type(RARRAY_AREF(ary, i));        if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&            rb_equal(RARRAY_AREF(v, 0), key))            return v;    }    return Qnil;}

Returns the first elementele inself such thatele is an array andele[0] == object:

a = [{foo:0}, [2,4], [4,5,6], [4,5]]a.assoc(4)# => [4, 5, 6]

Returnsnil if no such element is found.

Related:Array#rassoc; see alsoMethods for Fetching.

Source
VALUErb_ary_at(VALUE ary, VALUE pos){    return rb_ary_entry(ary, NUM2LONG(pos));}

Returns the element ofself specified by the givenindex ornil if there is no such element;index must be aninteger-convertible object.

For non-negativeindex, returns the element ofself at offsetindex:

a = [:foo,'bar',2]a.at(0)# => :fooa.at(2)# => 2a.at(2.0)# => 2

For negativeindex, counts backwards from the end ofself:

a.at(-2)# => "bar"

Related:Array#[]; see alsoMethods for Fetching.

Source
static VALUErb_ary_bsearch(VALUE ary){    VALUE index_result = rb_ary_bsearch_index(ary);    if (FIXNUM_P(index_result)) {        return rb_ary_entry(ary, FIX2LONG(index_result));    }    return index_result;}

Returns the element fromself found by a binary search, ornil if the search found no suitable element.

SeeBinary Searching.

Related: seeMethods for Fetching.

Source
static VALUErb_ary_bsearch_index(VALUE ary){    long low = 0, high = RARRAY_LEN(ary), mid;    int smaller = 0, satisfied = 0;    VALUE v, val;    RETURN_ENUMERATOR(ary, 0, 0);    while (low < high) {        mid = low + ((high - low) / 2);        val = rb_ary_entry(ary, mid);        v = rb_yield(val);        if (FIXNUM_P(v)) {            if (v == INT2FIX(0)) return INT2FIX(mid);            smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */        }        else if (v == Qtrue) {            satisfied = 1;            smaller = 1;        }        else if (!RTEST(v)) {            smaller = 0;        }        else if (rb_obj_is_kind_of(v, rb_cNumeric)) {            const VALUE zero = INT2FIX(0);            switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {              case 0: return INT2FIX(mid);              case 1: smaller = 0; break;              case -1: smaller = 1;            }        }        else {            rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE                     " (must be numeric, true, false or nil)",                     rb_obj_class(v));        }        if (smaller) {            high = mid;        }        else {            low = mid + 1;        }    }    if (!satisfied) return Qnil;    return INT2FIX(low);}

Returns the integer index of the element fromself found by a binary search, ornil if the search found no suitable element.

SeeBinary Searching.

Related: seeMethods for Fetching.

Source
VALUErb_ary_clear(VALUE ary){    rb_ary_modify_check(ary);    if (ARY_SHARED_P(ary)) {        rb_ary_unshare(ary);        FL_SET_EMBED(ary);        ARY_SET_EMBED_LEN(ary, 0);    }    else {        ARY_SET_LEN(ary, 0);        if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {            ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);        }    }    ary_verify(ary);    return ary;}

Removes all elements fromself; returnsself:

a = [:foo,'bar',2]a.clear# => []

Related: seeMethods for Deleting.

Source
static VALUErb_ary_collect(VALUE ary){    long i;    VALUE collect;    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    collect = rb_ary_new2(RARRAY_LEN(ary));    for (i = 0; i < RARRAY_LEN(ary); i++) {        rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));    }    return collect;}

With a block given, calls the block with each element ofself; returns a new array whose elements are the return values from the block:

a = [:foo,'bar',2]a1 =a.map {|element|element.class }a1# => [Symbol, String, Integer]

With no block given, returns a newEnumerator.

Related:collect!; see alsoMethods for Converting.

Also aliased as:map
Source
static VALUErb_ary_collect_bang(VALUE ary){    long i;    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    rb_ary_modify(ary);    for (i = 0; i < RARRAY_LEN(ary); i++) {        rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));    }    return ary;}

With a block given, calls the block with each element ofself and replaces the element with the block’s return value; returnsself:

a = [:foo,'bar',2]a.map! {|element|element.class }# => [Symbol, String, Integer]

With no block given, returns a newEnumerator.

Related:collect; see alsoMethods for Converting.

Also aliased as:map!
Source
static VALUErb_ary_combination(VALUE ary, VALUE num){    long i, n, len;    n = NUM2LONG(num);    RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);    len = RARRAY_LEN(ary);    if (n < 0 || len < n) {        /* yield nothing */    }    else if (n == 0) {        rb_yield(rb_ary_new2(0));    }    else if (n == 1) {        for (i = 0; i < RARRAY_LEN(ary); i++) {            rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));        }    }    else {        VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */        volatile VALUE t0;        long *stack = ALLOCV_N(long, t0, n+1);        RBASIC_CLEAR_CLASS(ary0);        combinate0(len, n, stack, ary0);        ALLOCV_END(t0);        RBASIC_SET_CLASS_RAW(ary0, rb_cArray);    }    return ary;}

When a block and a positiveinteger-convertible object argumentcount (0 < count <= self.size) are given, calls the block with each combination ofself of sizecount; returnsself:

a =%w[a b c]# => ["a", "b", "c"]a.combination(2) {|combination|pcombination }# => ["a", "b", "c"]

Output:

["a","b"]["a","c"]["b","c"]

The order of the yielded combinations is not guaranteed.

Whencount is zero, calls the block once with a new empty array:

a.combination(0) {|combination|pcombination }[].combination(0) {|combination|pcombination }

Output:

[][]

Whencount is negative or larger thanself.size andself is non-empty, does not call the block:

a.combination(-1) {|combination|fail'Cannot happen' }# => ["a", "b", "c"]a.combination(4)  {|combination|fail'Cannot happen' }# => ["a", "b", "c"]

With no block given, returns a newEnumerator.

Related:Array#permutation; see alsoMethods for Iterating.

Source
static VALUErb_ary_compact(VALUE ary){    ary = rb_ary_dup(ary);    rb_ary_compact_bang(ary);    return ary;}

Returns a new array containing only the non-nil elements fromself; element order is preserved:

a = [nil,0,nil,false,nil,'',nil, [],nil, {}]a.compact# => [0, false, "", [], {}]

Related:Array#compact!; see alsoMethods for Deleting.

Source
static VALUErb_ary_compact_bang(VALUE ary){    VALUE *p, *t, *end;    long n;    rb_ary_modify(ary);    p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */    end = p + RARRAY_LEN(ary);    while (t < end) {        if (NIL_P(*t)) t++;        else *p++ = *t++;    }    n = p - RARRAY_CONST_PTR(ary);    if (RARRAY_LEN(ary) == n) {        return Qnil;    }    ary_resize_smaller(ary, n);    return ary;}

Removes allnil elements fromself; Returnsself if any elements are removed,nil otherwise:

a = [nil,0,nil,false,nil,'',nil, [],nil, {}]a.compact!# => [0, false, "", [], {}]a# => [0, false, "", [], {}]a.compact!# => nil

Related:Array#compact; see alsoMethods for Deleting.

Source
static VALUErb_ary_concat_multi(int argc, VALUE *argv, VALUE ary){    rb_ary_modify_check(ary);    if (argc == 1) {        rb_ary_concat(ary, argv[0]);    }    else if (argc > 1) {        int i;        VALUE args = rb_ary_hidden_new(argc);        for (i = 0; i < argc; i++) {            rb_ary_concat(args, argv[i]);        }        ary_append(ary, args);    }    ary_verify(ary);    return ary;}

Adds toself all elements from each array inother_arrays; returnsself:

a = [0,1]a.concat(['two','three'], [:four,:five],a)# => [0, 1, "two", "three", :four, :five, 0, 1]

Related: seeMethods for Assigning.

Source
static VALUErb_ary_count(int argc, VALUE *argv, VALUE ary){    long i, n = 0;    if (rb_check_arity(argc, 0, 1) == 0) {        VALUE v;        if (!rb_block_given_p())            return LONG2NUM(RARRAY_LEN(ary));        for (i = 0; i < RARRAY_LEN(ary); i++) {            v = RARRAY_AREF(ary, i);            if (RTEST(rb_yield(v))) n++;        }    }    else {        VALUE obj = argv[0];        if (rb_block_given_p()) {            rb_warn("given block not used");        }        for (i = 0; i < RARRAY_LEN(ary); i++) {            if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;        }    }    return LONG2NUM(n);}

Returns a count of specified elements.

With no argument and no block, returns the count of all elements:

[0,:one,'two',3,3.0].count# => 5

With argumentobject given, returns the count of elements== toobject:

[0,:one,'two',3,3.0].count(3)# => 2

With no argument and a block given, calls the block with each element; returns the count of elements for which the block returns a truthy value:

[0,1,2,3].count {|element|element>1 }# => 2

With argumentobject and a block given, issues a warning, ignores the block, and returns the count of elements== toobject.

Related: seeMethods for Querying.

Source
static VALUErb_ary_cycle(int argc, VALUE *argv, VALUE ary){    long n, i;    rb_check_arity(argc, 0, 1);    RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);    if (argc == 0 || NIL_P(argv[0])) {        n = -1;    }    else {        n = NUM2LONG(argv[0]);        if (n <= 0) return Qnil;    }    while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {        for (i=0; i<RARRAY_LEN(ary); i++) {            rb_yield(RARRAY_AREF(ary, i));        }    }    return Qnil;}

With a block given, may call the block, depending on the value of argumentcount;count must be aninteger-convertible object, ornil.

Whencount is positive, calls the block with each element, then does so repeatedly, until it has done socount times; returnsnil:

output = [][0,1].cycle(2) {|element|output.push(element) }# => niloutput# => [0, 1, 0, 1]

Whencount is zero or negative, does not call the block:

[0,1].cycle(0) {|element|fail'Cannot happen' }# => nil[0,1].cycle(-1) {|element|fail'Cannot happen' }# => nil

Whencount isnil, cycles forever:

# Prints 0 and 1 forever.[0,1].cycle {|element|putselement }[0,1].cycle(nil) {|element|putselement }

With no block given, returns a newEnumerator.

Related: seeMethods for Iterating.

Source
VALUErb_ary_delete(VALUE ary, VALUE item){    VALUE v = item;    long i1, i2;    for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {        VALUE e = RARRAY_AREF(ary, i1);        if (rb_equal(e, item)) {            v = e;            continue;        }        if (i1 != i2) {            rb_ary_store(ary, i2, e);        }        i2++;    }    if (RARRAY_LEN(ary) == i2) {        if (rb_block_given_p()) {            return rb_yield(item);        }        return Qnil;    }    ary_resize_smaller(ary, i2);    ary_verify(ary);    return v;}

Removes zero or more elements fromself.

With no block given, removes fromself each elementele such thatele == object; returns the last removed element:

a = [0,1,2,2.0]a.delete(2)# => 2.0a# => [0, 1]

Returnsnil if no elements removed:

a.delete(2)# => nil

With a block given, removes fromself each elementele such thatele == object.

If any such elements are found, ignores the block and returns the last removed element:

a = [0,1,2,2.0]a.delete(2) {|element|fail'Cannot happen' }# => 2.0a# => [0, 1]

If no such element is found, returns the block’s return value:

a.delete(2) {|element|"Element #{element} not found." }# => "Element 2 not found."

Related: seeMethods for Deleting.

Source
static VALUErb_ary_delete_at_m(VALUE ary, VALUE pos){    return rb_ary_delete_at(ary, NUM2LONG(pos));}

Removes the element ofself at the givenindex, which must be aninteger-convertible object.

Whenindex is non-negative, deletes the element at offsetindex:

a = [:foo,'bar',2]a.delete_at(1)# => "bar"a# => [:foo, 2]

Whenindex is negative, counts backward from the end of the array:

a = [:foo,'bar',2]a.delete_at(-2)# => "bar"a# => [:foo, 2]

Whenindex is out of range, returnsnil.

a = [:foo,'bar',2]a.delete_at(3)# => nila.delete_at(-4)# => nil

Related: seeMethods for Deleting.

Source
static VALUErb_ary_delete_if(VALUE ary){    ary_verify(ary);    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    ary_reject_bang(ary);    return ary;}

With a block given, calls the block with each element ofself; removes the element if the block returns a truthy value; returnsself:

a = [:foo,'bar',2,'bat']a.delete_if {|element|element.to_s.start_with?('b') }# => [:foo, 2]

With no block given, returns a newEnumerator.

Related: seeMethods for Deleting.

Source
static VALUErb_ary_difference_multi(int argc, VALUE *argv, VALUE ary){    VALUE ary_diff;    long i, length;    volatile VALUE t0;    bool *is_hash = ALLOCV_N(bool, t0, argc);    ary_diff = rb_ary_new();    length = RARRAY_LEN(ary);    for (i = 0; i < argc; i++) {        argv[i] = to_ary(argv[i]);        is_hash[i] = (length > SMALL_ARRAY_LEN && RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);        if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);    }    for (i = 0; i < RARRAY_LEN(ary); i++) {        int j;        VALUE elt = rb_ary_elt(ary, i);        for (j = 0; j < argc; j++) {            if (is_hash[j]) {                if (rb_hash_stlike_lookup(argv[j], elt, NULL))                    break;            }            else {                if (rb_ary_includes_by_eql(argv[j], elt)) break;            }        }        if (j == argc) rb_ary_push(ary_diff, elt);    }    ALLOCV_END(t0);    return ary_diff;}

Returns a new array containing only those elements fromself that are not found in any of the givenother_arrays; items are compared usingeql?; order fromself is preserved:

[0,1,1,2,1,1,3,1,1].difference([1])# => [0, 2, 3][0,1,2,3].difference([3,0], [1,3])# => [2][0,1,2].difference([4])# => [0, 1, 2][0,1,2].difference# => [0, 1, 2]

Returns a copy ofself if no arguments are given.

Related:Array#-; see alsoMethods for Combining.

Source
static VALUErb_ary_dig(int argc, VALUE *argv, VALUE self){    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);    self = rb_ary_at(self, *argv);    if (!--argc) return self;    ++argv;    return rb_obj_dig(argc, argv, self, Qnil);}

Finds and returns the object in nested object specified byindex andidentifiers; the nested objects may be instances of various classes. SeeDig Methods.

Examples:

a = [:foo, [:bar,:baz, [:bat,:bam]]]a.dig(1)# => [:bar, :baz, [:bat, :bam]]a.dig(1,2)# => [:bat, :bam]a.dig(1,2,0)# => :bata.dig(1,2,3)# => nil

Related: seeMethods for Fetching.

Source
static VALUErb_ary_drop(VALUE ary, VALUE n){    VALUE result;    long pos = NUM2LONG(n);    if (pos < 0) {        rb_raise(rb_eArgError, "attempt to drop negative size");    }    result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));    if (NIL_P(result)) result = rb_ary_new();    return result;}

Returns a new array containing all but the firstcount element ofself, wherecount is a non-negative integer; does not modifyself.

Examples:

a = [0,1,2,3,4,5]a.drop(0)# => [0, 1, 2, 3, 4, 5]a.drop(1)# => [1, 2, 3, 4, 5]a.drop(2)# => [2, 3, 4, 5]a.drop(9)# => []

Related: seeMethods for Fetching.

Source
static VALUErb_ary_drop_while(VALUE ary){    long i;    RETURN_ENUMERATOR(ary, 0, 0);    for (i = 0; i < RARRAY_LEN(ary); i++) {        if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;    }    return rb_ary_drop(ary, LONG2FIX(i));}

With a block given, calls the block with each successive element ofself; stops if the block returnsfalse ornil; returns a new arrayomitting those elements for which the block returned a truthy value; does not modifyself:

a = [0,1,2,3,4,5]a.drop_while {|element|element<3 }# => [3, 4, 5]

With no block given, returns a newEnumerator.

Related: seeMethods for Fetching.

Source
VALUErb_ary_each(VALUE ary){    long i;    ary_verify(ary);    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    for (i=0; i<RARRAY_LEN(ary); i++) {        rb_yield(RARRAY_AREF(ary, i));    }    return ary;}

With a block given, iterates over the elements ofself, passing each element to the block; returnsself:

a = [:foo,'bar',2]a.each {|element|puts"#{element.class} #{element}" }

Output:

SymbolfooStringbarInteger2

Allows the array to be modified during iteration:

a = [:foo,'bar',2]a.each {|element|putselement;a.clearifelement.to_s.start_with?('b') }

Output:

foobar

With no block given, returns a newEnumerator.

Related: seeMethods for Iterating.

Source
static VALUErb_ary_each_index(VALUE ary){    long i;    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    for (i=0; i<RARRAY_LEN(ary); i++) {        rb_yield(LONG2NUM(i));    }    return ary;}

With a block given, iterates over the elements ofself, passing eacharray index to the block; returnsself:

a = [:foo,'bar',2]a.each_index {|index|puts"#{index} #{a[index]}" }

Output:

0 foo1 bar2 2

Allows the array to be modified during iteration:

a = [:foo,'bar',2]a.each_index {|index|putsindex;a.clearifindex>0 }a# => []

Output:

01

With no block given, returns a newEnumerator.

Related: seeMethods for Iterating.

Source
static VALUErb_ary_empty_p(VALUE ary){    return RBOOL(RARRAY_LEN(ary) == 0);}

Returnstrue if the count of elements inself is zero,false otherwise.

Related: seeMethods for Querying.

Source
static VALUErb_ary_eql(VALUE ary1, VALUE ary2){    if (ary1 == ary2) return Qtrue;    if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;    if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;    if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;    return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);}

Returnstrue ifself andother_array are the same size, and if, for each indexi inself,self[i].eql?(other_array[i]):

a0 = [:foo,'bar',2]a1 = [:foo,'bar',2]a1.eql?(a0)# => true

Otherwise, returnsfalse.

This method is different from methodArray#==, which compares using methodObject#==.

Related: seeMethods for Querying.

Source
static VALUErb_ary_fetch(int argc, VALUE *argv, VALUE ary){    VALUE pos, ifnone;    long block_given;    long idx;    rb_scan_args(argc, argv, "11", &pos, &ifnone);    block_given = rb_block_given_p();    if (block_given && argc == 2) {        rb_warn("block supersedes default value argument");    }    idx = NUM2LONG(pos);    if (idx < 0) {        idx +=  RARRAY_LEN(ary);    }    if (idx < 0 || RARRAY_LEN(ary) <= idx) {        if (block_given) return rb_yield(pos);        if (argc == 1) {            rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",                        idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));        }        return ifnone;    }    return RARRAY_AREF(ary, idx);}

Returns the element ofself at offsetindex ifindex is in range;index must be aninteger-convertible object.

With the single argumentindex and no block, returns the element at offsetindex:

a = [:foo,'bar',2]a.fetch(1)# => "bar"a.fetch(1.1)# => "bar"

Ifindex is negative, counts from the end of the array:

a = [:foo,'bar',2]a.fetch(-1)# => 2a.fetch(-2)# => "bar"

With argumentsindex anddefault_value (which may be any object) and no block, returnsdefault_value ifindex is out-of-range:

a = [:foo,'bar',2]a.fetch(1,nil)# => "bar"a.fetch(3,:foo)# => :foo

With argumentindex and a block, returns the element at offsetindex if index is in range (and the block is not called); otherwise calls the block with index and returns its return value:

a = [:foo,'bar',2]a.fetch(1) {|index|raise'Cannot happen' }# => "bar"a.fetch(50) {|index|"Value for #{index}" }# => "Value for 50"

Related: seeMethods for Fetching.

Source
# File array.rb, line 210deffetch_values(*indexes,&block)indexes.map! {|i|fetch(i,&block) }indexesend

With no block given, returns a new array containing the elements ofself at the offsets specified byindexes. Each of theindexes must be aninteger-convertible object:

a = [:foo,:bar,:baz]a.fetch_values(2,0)# => [:baz, :foo]a.fetch_values(2.1,0)# => [:baz, :foo]a.fetch_values# => []

For a negative index, counts backwards from the end of the array:

a.fetch_values(-2,-1)# [:bar, :baz]

When no block is given, raises an exception if any index is out of range.

With a block given, for each index:

  • If the index is in range, uses an element ofself (as above).

  • Otherwise, calls the block with the index and uses the block’s return value.

Example:

a = [:foo,:bar,:baz]a.fetch_values(1,0,42,777) {|index|index.to_s }# => [:bar, :foo, "42", "777"]

Related: seeMethods for Fetching.

Source
static VALUErb_ary_fill(int argc, VALUE *argv, VALUE ary){    VALUE item = Qundef, arg1, arg2;    long beg = 0, end = 0, len = 0;    if (rb_block_given_p()) {        rb_scan_args(argc, argv, "02", &arg1, &arg2);        argc += 1;              /* hackish */    }    else {        rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);    }    switch (argc) {      case 1:        beg = 0;        len = RARRAY_LEN(ary);        break;      case 2:        if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {            break;        }        /* fall through */      case 3:        beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);        if (beg < 0) {            beg = RARRAY_LEN(ary) + beg;            if (beg < 0) beg = 0;        }        len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);        break;    }    rb_ary_modify(ary);    if (len < 0) {        return ary;    }    if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {        rb_raise(rb_eArgError, "argument too big");    }    end = beg + len;    if (RARRAY_LEN(ary) < end) {        if (end >= ARY_CAPA(ary)) {            ary_resize_capa(ary, end);        }        ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));        ARY_SET_LEN(ary, end);    }    if (UNDEF_P(item)) {        VALUE v;        long i;        for (i=beg; i<end; i++) {            v = rb_yield(LONG2NUM(i));            if (i>=RARRAY_LEN(ary)) break;            ARY_SET(ary, i, v);        }    }    else {        ary_memfill(ary, beg, len, item);    }    return ary;}

Replaces selected elements inself; may add elements toself; always returnsself (never a new array).

In brief:

# Non-negative start.['a','b','c','d'].fill('-',1,2)# => ["a", "-", "-", "d"]['a','b','c','d'].fill(1,2) {|e|e.to_s }# => ["a", "1", "2", "d"]# Extends with specified values if necessary.['a','b','c','d'].fill('-',3,2)# => ["a", "b", "c", "-", "-"]['a','b','c','d'].fill(3,2) {|e|e.to_s }# => ["a", "b", "c", "3", "4"]# Fills with nils if necessary.['a','b','c','d'].fill('-',6,2)# => ["a", "b", "c", "d", nil, nil, "-", "-"]['a','b','c','d'].fill(6,2) {|e|e.to_s }# => ["a", "b", "c", "d", nil, nil, "6", "7"]# For negative start, counts backwards from the end.['a','b','c','d'].fill('-',-3,3)# => ["a", "-", "-", "-"]['a','b','c','d'].fill(-3,3) {|e|e.to_s }# => ["a", "1", "2", "3"]# Range.['a','b','c','d'].fill('-',1..2)# => ["a", "-", "-", "d"]['a','b','c','d'].fill(1..2) {|e|e.to_s }# => ["a", "1", "2", "d"]

When argumentsstart andcount are given, they select the elements ofself to be replaced; each must be aninteger-convertible object (ornil):

  • start specifies the zero-based offset of the first element to be replaced;nil means zero.

  • count is the number of consecutive elements to be replaced;nil means “all the rest.”

With argumentobject given, that one object is used for all replacements:

o =Object.new# => #<Object:0x0000014e7bff7600>a = ['a','b','c','d']# => ["a", "b", "c", "d"]a.fill(o,1,2)# => ["a", #<Object:0x0000014e7bff7600>, #<Object:0x0000014e7bff7600>, "d"]

With a block given, the block is called once for each element to be replaced; the value passed to the block is theindex of the element to be replaced (not the element itself); the block’s return value replaces the element:

a = ['a','b','c','d']# => ["a", "b", "c", "d"]a.fill(1,2) {|element|element.to_s }# => ["a", "1", "2", "d"]

For argumentsstart andcount:

  • Ifstart is non-negative, replacescount elements beginning at offsetstart:

    ['a','b','c','d'].fill('-',0,2)# => ["-", "-", "c", "d"]['a','b','c','d'].fill('-',1,2)# => ["a", "-", "-", "d"]['a','b','c','d'].fill('-',2,2)# => ["a", "b", "-", "-"]['a','b','c','d'].fill(0,2) {|e|e.to_s }# => ["0", "1", "c", "d"]['a','b','c','d'].fill(1,2) {|e|e.to_s }# => ["a", "1", "2", "d"]['a','b','c','d'].fill(2,2) {|e|e.to_s }# => ["a", "b", "2", "3"]

    Extendsself if necessary:

    ['a','b','c','d'].fill('-',3,2)# => ["a", "b", "c", "-", "-"]['a','b','c','d'].fill('-',4,2)# => ["a", "b", "c", "d", "-", "-"]['a','b','c','d'].fill(3,2) {|e|e.to_s }# => ["a", "b", "c", "3", "4"]['a','b','c','d'].fill(4,2) {|e|e.to_s }# => ["a", "b", "c", "d", "4", "5"]

    Fills withnil if necessary:

    ['a','b','c','d'].fill('-',5,2)# => ["a", "b", "c", "d", nil, "-", "-"]['a','b','c','d'].fill('-',6,2)# => ["a", "b", "c", "d", nil, nil, "-", "-"]['a','b','c','d'].fill(5,2) {|e|e.to_s }# => ["a", "b", "c", "d", nil, "5", "6"]['a','b','c','d'].fill(6,2) {|e|e.to_s }# => ["a", "b", "c", "d", nil, nil, "6", "7"]

    Does nothing ifcount is non-positive:

    ['a','b','c','d'].fill('-',2,0)# => ["a", "b", "c", "d"]['a','b','c','d'].fill('-',2,-100)# => ["a", "b", "c", "d"]['a','b','c','d'].fill('-',6,-100)# => ["a", "b", "c", "d"]['a','b','c','d'].fill(2,0) {|e|fail'Cannot happen' }# => ["a", "b", "c", "d"]['a','b','c','d'].fill(2,-100) {|e|fail'Cannot happen' }# => ["a", "b", "c", "d"]['a','b','c','d'].fill(6,-100) {|e|fail'Cannot happen' }# => ["a", "b", "c", "d"]
  • Ifstart is negative, counts backwards from the end ofself:

    ['a','b','c','d'].fill('-',-4,3)# => ["-", "-", "-", "d"]['a','b','c','d'].fill('-',-3,3)# => ["a", "-", "-", "-"]['a','b','c','d'].fill(-4,3) {|e|e.to_s }# => ["0", "1", "2", "d"]['a','b','c','d'].fill(-3,3) {|e|e.to_s }# => ["a", "1", "2", "3"]

    Extendsself if necessary:

    ['a','b','c','d'].fill('-',-2,3)# => ["a", "b", "-", "-", "-"]['a','b','c','d'].fill('-',-1,3)# => ["a", "b", "c", "-", "-", "-"]['a','b','c','d'].fill(-2,3) {|e|e.to_s }# => ["a", "b", "2", "3", "4"]['a','b','c','d'].fill(-1,3) {|e|e.to_s }# => ["a", "b", "c", "3", "4", "5"]

    Starts at the beginning ofself ifstart is negative and out-of-range:

    ['a','b','c','d'].fill('-',-5,2)# => ["-", "-", "c", "d"]['a','b','c','d'].fill('-',-6,2)# => ["-", "-", "c", "d"]['a','b','c','d'].fill(-5,2) {|e|e.to_s }# => ["0", "1", "c", "d"]['a','b','c','d'].fill(-6,2) {|e|e.to_s }# => ["0", "1", "c", "d"]

    Does nothing ifcount is non-positive:

    ['a','b','c','d'].fill('-',-2,0)# => ["a", "b", "c", "d"]['a','b','c','d'].fill('-',-2,-1)# => ["a", "b", "c", "d"]['a','b','c','d'].fill(-2,0) {|e|fail'Cannot happen' }# => ["a", "b", "c", "d"]['a','b','c','d'].fill(-2,-1) {|e|fail'Cannot happen' }# => ["a", "b", "c", "d"]

When argumentrange is given, it must be aRange object whose members are numeric; itsbegin andend values determine the elements ofself to be replaced:

  • If bothbegin andend are positive, they specify the first and last elements to be replaced:

    ['a','b','c','d'].fill('-',1..2)# => ["a", "-", "-", "d"]['a','b','c','d'].fill(1..2) {|e|e.to_s }# => ["a", "1", "2", "d"]

    Ifend is smaller thanbegin, replaces no elements:

    ['a','b','c','d'].fill('-',2..1)# => ["a", "b", "c", "d"]['a','b','c','d'].fill(2..1) {|e|e.to_s }# => ["a", "b", "c", "d"]
  • If either is negative (or both are negative), counts backwards from the end ofself:

    ['a','b','c','d'].fill('-',-3..2)# => ["a", "-", "-", "d"]['a','b','c','d'].fill('-',1..-2)# => ["a", "-", "-", "d"]['a','b','c','d'].fill('-',-3..-2)# => ["a", "-", "-", "d"]['a','b','c','d'].fill(-3..2) {|e|e.to_s }# => ["a", "1", "2", "d"]['a','b','c','d'].fill(1..-2) {|e|e.to_s }# => ["a", "1", "2", "d"]['a','b','c','d'].fill(-3..-2) {|e|e.to_s }# => ["a", "1", "2", "d"]
  • If theend value is excluded (seeRange#exclude_end?), omits the last replacement:

    ['a','b','c','d'].fill('-',1...2)# => ["a", "-", "c", "d"]['a','b','c','d'].fill('-',1...-2)# => ["a", "-", "c", "d"]['a','b','c','d'].fill(1...2) {|e|e.to_s }# => ["a", "1", "c", "d"]['a','b','c','d'].fill(1...-2) {|e|e.to_s }# => ["a", "1", "c", "d"]
  • If the range is endless (seeEndless Ranges), replaces elements to the end ofself:

    ['a','b','c','d'].fill('-',1..)# => ["a", "-", "-", "-"]['a','b','c','d'].fill(1..) {|e|e.to_s }# => ["a", "1", "2", "3"]
  • If the range is beginless (seeBeginless Ranges), replaces elements from the beginning ofself:

    ['a','b','c','d'].fill('-',..2)# => ["-", "-", "-", "d"]['a','b','c','d'].fill(..2) {|e|e.to_s }# => ["0", "1", "2", "d"]

Related: seeMethods for Assigning.

With a block given, calls the block with each element ofself; returns a new array containing those elements ofself for which the block returns a truthy value:

a = [:foo,'bar',2,:bam]a.select {|element|element.to_s.start_with?('b') }# => ["bar", :bam]

With no block given, returns a newEnumerator.

Related: seeMethods for Fetching.

Alias for:select

With a block given, calls the block with each element ofself; removes fromself those elements for which the block returnsfalse ornil.

Returnsself if any elements were removed:

a = [:foo,'bar',2,:bam]a.select! {|element|element.to_s.start_with?('b') }# => ["bar", :bam]

Returnsnil if no elements were removed.

With no block given, returns a newEnumerator.

Related: seeMethods for Deleting.

Alias for:select!
Source
Also aliased as:index
Source
# File array.rb, line 129deffirstn =unspecified =trueifPrimitive.mandatory_only?Primitive.attr!:leafPrimitive.cexpr!%q{ ary_first(self) }elseifunspecifiedPrimitive.cexpr!%q{ ary_first(self) }elsePrimitive.cexpr!%q{  ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_FIRST) }endendend

Returns elements fromself, ornil; does not modifyself.

With no argument given, returns the first element (if available):

a = [:foo,'bar',2]a.first# => :fooa# => [:foo, "bar", 2]

Ifself is empty, returnsnil.

[].first# => nil

With a non-negative integer argumentcount given, returns the firstcount elements (as available) in a new array:

a.first(0)# => []a.first(2)# => [:foo, "bar"]a.first(50)# => [:foo, "bar", 2]

Related: seeMethods for Querying.

Source
static VALUErb_ary_flatten(int argc, VALUE *argv, VALUE ary){    int level = -1;    VALUE result;    if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {        level = NUM2INT(argv[0]);        if (level == 0) return ary_make_shared_copy(ary);    }    result = flatten(ary, level);    if (result == ary) {        result = ary_make_shared_copy(ary);    }    return result;}

Returns a new array that is a recursive flattening ofself todepth levels of recursion;depth must be aninteger-convertible object ornil. At each level of recursion:

  • Each element that is an array is “flattened” (that is, replaced by its individual array elements).

  • Each element that is not an array is unchanged (even if the element is an object that has instance methodflatten).

With non-negative integer argumentdepth, flattens recursively throughdepth levels:

a = [0, [1, [2,3],4 ],5, {foo:0},Set.new([6,7]) ]a# => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]a.flatten(0)# => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]a.flatten(1  )# => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]a.flatten(1.1)# => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]a.flatten(2)# => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]a.flatten(3)# => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]

Withnil or negativedepth, flattens all levels.

a.flatten# => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]a.flatten(-1)# => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]

Related:Array#flatten!; see alsoMethods for Converting.

Source
static VALUErb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary){    int mod = 0, level = -1;    VALUE result, lv;    lv = (rb_check_arity(argc, 0, 1) ? argv[0] : Qnil);    rb_ary_modify_check(ary);    if (!NIL_P(lv)) level = NUM2INT(lv);    if (level == 0) return Qnil;    result = flatten(ary, level);    if (result == ary) {        return Qnil;    }    if (!(mod = ARY_EMBED_P(result))) rb_ary_freeze(result);    rb_ary_replace(ary, result);    if (mod) ARY_SET_EMBED_LEN(result, 0);    return ary;}

Returnsself as a recursively flattening ofself todepth levels of recursion;depth must be aninteger-convertible object, ornil. At each level of recursion:

  • Each element that is an array is “flattened” (that is, replaced by its individual array elements).

  • Each element that is not an array is unchanged (even if the element is an object that has instance methodflatten).

Returnsnil if no elements were flattened.

With non-negative integer argumentdepth, flattens recursively throughdepth levels:

a = [0, [1, [2,3],4 ],5, {foo:0},Set.new([6,7]) ]a# => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]a.dup.flatten!(1)# => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]a.dup.flatten!(1.1)# => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]a.dup.flatten!(2)# => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]a.dup.flatten!(3)# => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]

Withnil or negative argumentdepth, flattens all levels:

a.dup.flatten!# => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]a.dup.flatten!(-1)# => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]

Related:Array#flatten; see alsoMethods for Assigning.

Source
VALUErb_ary_freeze(VALUE ary){    RUBY_ASSERT(RB_TYPE_P(ary, T_ARRAY));    if (OBJ_FROZEN(ary)) return ary;    if (!ARY_EMBED_P(ary) && !ARY_SHARED_P(ary) && !ARY_SHARED_ROOT_P(ary)) {        ary_shrink_capa(ary);    }    return rb_obj_freeze(ary);}

Freezesself (if not already frozen); returnsself:

a = []a.frozen?# => falsea.freezea.frozen?# => true

No further changes may be made toself; raisesFrozenError if a change is attempted.

Related:Kernel#frozen?.

Source
static VALUErb_ary_hash(VALUE ary){    RBIMPL_ASSERT_OR_ASSUME(ary);    return ary_hash_values(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary), ary);}

Returns the integer hash value forself.

Two arrays with the same content will have the same hash value (and will compare using eql?):

['a','b'].hash== ['a','b'].hash# => true['a','b'].hash== ['a','c'].hash# => false['a','b'].hash== ['a'].hash# => false
Source
VALUErb_ary_includes(VALUE ary, VALUE item){    long i;    VALUE e;    for (i=0; i<RARRAY_LEN(ary); i++) {        e = RARRAY_AREF(ary, i);        if (rb_equal(e, item)) {            return Qtrue;        }    }    return Qfalse;}

Returns whether for some elementelement inself,object == element:

[0,1,2].include?(2)# => true[0,1,2].include?(2.0)# => true[0,1,2].include?(2.1)# => false

Related: seeMethods for Querying.

Returns the zero-based integer index of a specified element, ornil.

With only argumentobject given, returns the index of the first elementelement for whichobject == element:

a = [:foo,'bar',2,'bar']a.index('bar')# => 1

Returnsnil if no such element found.

With only a block given, calls the block with each successive element; returns the index of the first element for which the block returns a truthy value:

a = [:foo,'bar',2,'bar']a.index {|element|element=='bar' }# => 1

Returnsnil if the block never returns a truthy value.

With neither an argument nor a block given, returns a newEnumerator.

Related: seeMethods for Querying.

Alias for:find_index
Source
VALUErb_ary_replace(VALUE copy, VALUE orig){    rb_ary_modify_check(copy);    orig = to_ary(orig);    if (copy == orig) return copy;    rb_ary_reset(copy);    /* orig has enough space to embed the contents of orig. */    if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) {        RUBY_ASSERT(ARY_EMBED_P(copy));        ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));        ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig));    }    /* orig is embedded but copy does not have enough space to embed the     * contents of orig. */    else if (ARY_EMBED_P(orig)) {        long len = ARY_EMBED_LEN(orig);        VALUE *ptr = ary_heap_alloc_buffer(len);        FL_UNSET_EMBED(copy);        ARY_SET_PTR(copy, ptr);        ARY_SET_LEN(copy, len);        ARY_SET_CAPA(copy, len);        // No allocation and exception expected that could leave `copy` in a        // bad state from the edits above.        ary_memcpy(copy, 0, len, RARRAY_CONST_PTR(orig));    }    /* Otherwise, orig is on heap and copy does not have enough space to embed     * the contents of orig. */    else {        VALUE shared_root = ary_make_shared(orig);        FL_UNSET_EMBED(copy);        ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));        ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));        rb_ary_set_shared(copy, shared_root);        RUBY_ASSERT(RB_OBJ_SHAREABLE_P(copy) ? RB_OBJ_SHAREABLE_P(shared_root) : 1);    }    ary_verify(copy);    return copy;}

Replaces the elements ofself with the elements ofother_array, which must be anarray-convertible object; returnsself:

a = ['a','b','c']# => ["a", "b", "c"]a.replace(['d','e'])# => ["d", "e"]

Related: seeMethods for Assigning.

Also aliased as:replace
Source
static VALUErb_ary_insert(int argc, VALUE *argv, VALUE ary){    long pos;    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);    rb_ary_modify_check(ary);    pos = NUM2LONG(argv[0]);    if (argc == 1) return ary;    if (pos == -1) {        pos = RARRAY_LEN(ary);    }    else if (pos < 0) {        long minpos = -RARRAY_LEN(ary) - 1;        if (pos < minpos) {            rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",                     pos, minpos);        }        pos++;    }    rb_ary_splice(ary, pos, 0, argv + 1, argc - 1);    return ary;}

Inserts the givenobjects as elements ofself; returnsself.

Whenindex is non-negative, insertsobjectsbefore the element at offsetindex:

a = ['a','b','c']# => ["a", "b", "c"]a.insert(1,:x,:y,:z)# => ["a", :x, :y, :z, "b", "c"]

Extends the array ifindex is beyond the array (index >= self.size):

a = ['a','b','c']# => ["a", "b", "c"]a.insert(5,:x,:y,:z)# => ["a", "b", "c", nil, nil, :x, :y, :z]

Whenindex is negative, insertsobjectsafter the element at offsetindex + self.size:

a = ['a','b','c']# => ["a", "b", "c"]a.insert(-2,:x,:y,:z)# => ["a", "b", :x, :y, :z, "c"]

With noobjects given, does nothing:

a = ['a','b','c']# => ["a", "b", "c"]a.insert(1)# => ["a", "b", "c"]a.insert(50)# => ["a", "b", "c"]a.insert(-50)# => ["a", "b", "c"]

RaisesIndexError ifobjects are given andindex is negative and out of range.

Related: seeMethods for Assigning.

Source
static VALUErb_ary_inspect(VALUE ary){    if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");    return rb_exec_recursive(inspect_ary, ary, 0);}

Returns the new string formed by calling methodinspect on each array element:

a = [:foo,'bar',2]a.inspect# => "[:foo, \"bar\", 2]"

Related: seeMethods for Converting.

Also aliased as:to_s
Source
static VALUErb_ary_intersect_p(VALUE ary1, VALUE ary2){    VALUE hash, v, result, shorter, longer;    st_data_t vv;    long i;    ary2 = to_ary(ary2);    if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return Qfalse;    if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {        for (i=0; i<RARRAY_LEN(ary1); i++) {            v = RARRAY_AREF(ary1, i);            if (rb_ary_includes_by_eql(ary2, v)) return Qtrue;        }        return Qfalse;    }    shorter = ary1;    longer = ary2;    if (RARRAY_LEN(ary1) > RARRAY_LEN(ary2)) {        longer = ary1;        shorter = ary2;    }    hash = ary_make_hash(shorter);    result = Qfalse;    for (i=0; i<RARRAY_LEN(longer); i++) {        v = RARRAY_AREF(longer, i);        vv = (st_data_t)v;        if (rb_hash_stlike_lookup(hash, vv, 0)) {            result = Qtrue;            break;        }    }    return result;}

Returns whetherother_array has at least one element that iseql? to some element ofself:

[1,2,3].intersect?([3,4,5])# => true[1,2,3].intersect?([4,5,6])# => false

Each element must correctly implement methodhash.

Related: seeMethods for Querying.

Source
static VALUErb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary){    VALUE result = rb_ary_dup(ary);    int i;    for (i = 0; i < argc; i++) {        result = rb_ary_and(result, argv[i]);    }    return result;}

Returns a new array containing each element inself that iseql? to at least one element in each of the givenother_arrays; duplicates are omitted:

[0,0,1,1,2,3].intersection([0,1,2], [0,1,3])# => [0, 1]

Each element must correctly implement methodhash.

Order fromself is preserved:

[0,1,2].intersection([2,1,0])# => [0, 1, 2]

Returns a copy ofself if no arguments are given.

Related: seeMethods for Combining.

Source
static VALUErb_ary_join_m(int argc, VALUE *argv, VALUE ary){    VALUE sep;    if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(sep = argv[0])) {        sep = rb_output_fs;        if (!NIL_P(sep)) {            rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");        }    }    return rb_ary_join(ary, sep);}

Returns the new string formed by joining the converted elements ofself; for each elementelement:

  • Converts recursively usingelement.join(separator) ifelement is akind_of?(Array).

  • Otherwise, converts usingelement.to_s.

With no argument given, joins using the output field separator,$,:

a = [:foo,'bar',2]$,# => nila.join# => "foobar2"

With string argumentseparator given, joins using that separator:

a = [:foo,'bar',2]a.join("\n")# => "foo\nbar\n2"

Joins recursively for nested arrays:

a = [:foo, [:bar, [:baz,:bat]]]a.join# => "foobarbazbat"

Related: seeMethods for Converting.

Source
static VALUErb_ary_keep_if(VALUE ary){    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    rb_ary_select_bang(ary);    return ary;}

With a block given, calls the block with each element ofself; removes the element fromself if the block does not return a truthy value:

a = [:foo,'bar',2,:bam]a.keep_if {|element|element.to_s.start_with?('b') }# => ["bar", :bam]

With no block given, returns a newEnumerator.

Related: seeMethods for Deleting.

Source
# File array.rb, line 166deflastn =unspecified =trueifPrimitive.mandatory_only?Primitive.attr!:leafPrimitive.cexpr!%q{ ary_last(self) }elseifunspecifiedPrimitive.cexpr!%q{ ary_last(self) }elsePrimitive.cexpr!%q{ ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_LAST) }endendend

Returns elements fromself, ornil;self is not modified.

With no argument given, returns the last element, ornil ifself is empty:

a = [:foo,'bar',2]a.last# => 2a# => [:foo, "bar", 2][].last# => nil

With non-negative integer argumentcount given, returns a new array containing the trailingcount elements ofself, as available:

a = [:foo,'bar',2]a.last(2)# => ["bar", 2]a.last(50)# => [:foo, "bar", 2]a.last(0)# => [][].last(3)# => []

Related: seeMethods for Fetching.

Source
static VALUErb_ary_length(VALUE ary){    long len = RARRAY_LEN(ary);    return LONG2NUM(len);}

Returns the count of elements inself:

[0,1,2].length# => 3[].length# => 0

Related: seeMethods for Querying.

Also aliased as:size

With a block given, calls the block with each element ofself; returns a new array whose elements are the return values from the block:

a = [:foo,'bar',2]a1 =a.map {|element|element.class }a1# => [Symbol, String, Integer]

With no block given, returns a newEnumerator.

Related:collect!; see alsoMethods for Converting.

Also aliased as: collect
Alias for:collect

With a block given, calls the block with each element ofself and replaces the element with the block’s return value; returnsself:

a = [:foo,'bar',2]a.map! {|element|element.class }# => [Symbol, String, Integer]

With no block given, returns a newEnumerator.

Related:collect; see alsoMethods for Converting.

Alias for:collect!
Source
static VALUErb_ary_max(int argc, VALUE *argv, VALUE ary){    VALUE result = Qundef, v;    VALUE num;    long i;    if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))       return rb_nmin_run(ary, num, 0, 1, 1);    const long n = RARRAY_LEN(ary);    if (rb_block_given_p()) {        for (i = 0; i < RARRAY_LEN(ary); i++) {           v = RARRAY_AREF(ary, i);           if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {               result = v;           }        }    }    else if (n > 0) {        result = RARRAY_AREF(ary, 0);        if (n > 1) {            if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {                return ary_max_opt_fixnum(ary, 1, result);            }            else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {                return ary_max_opt_string(ary, 1, result);            }            else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {                return ary_max_opt_float(ary, 1, result);            }            else {                return ary_max_generic(ary, 1, result);            }        }    }    if (UNDEF_P(result)) return Qnil;    return result;}

Returns one of the following:

  • The maximum-valued element fromself.

  • A new array of maximum-valued elements fromself.

Does not modifyself.

With no block given, each element inself must respond to method<=> with a numeric.

With no argument and no block, returns the element inself having the maximum value per method<=>:

[1,0,3,2].max# => 3

With non-negative numeric argumentcount and no block, returns a new array with at mostcount elements, in descending order, per method<=>:

[1,0,3,2].max(3)# => [3, 2, 1][1,0,3,2].max(3.0)# => [3, 2, 1][1,0,3,2].max(9)# => [3, 2, 1, 0][1,0,3,2].max(0)# => []

With a block given, the block must return a numeric.

With a block and no argument, calls the blockself.size - 1 times to compare elements; returns the element having the maximum value per the block:

['0','','000','00'].max {|a,b|a.size<=>b.size }# => "000"

With non-negative numeric argumentcount and a block, returns a new array with at mostcount elements, in descending order, per the block:

['0','','000','00'].max(2) {|a,b|a.size<=>b.size }# => ["000", "00"]

Related: seeMethods for Fetching.

Source
static VALUErb_ary_min(int argc, VALUE *argv, VALUE ary){    VALUE result = Qundef, v;    VALUE num;    long i;    if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))       return rb_nmin_run(ary, num, 0, 0, 1);    const long n = RARRAY_LEN(ary);    if (rb_block_given_p()) {        for (i = 0; i < RARRAY_LEN(ary); i++) {           v = RARRAY_AREF(ary, i);           if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {               result = v;           }        }    }    else if (n > 0) {        result = RARRAY_AREF(ary, 0);        if (n > 1) {            if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {                return ary_min_opt_fixnum(ary, 1, result);            }            else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {                return ary_min_opt_string(ary, 1, result);            }            else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {                return ary_min_opt_float(ary, 1, result);            }            else {                return ary_min_generic(ary, 1, result);            }        }    }    if (UNDEF_P(result)) return Qnil;    return result;}

Returns one of the following:

  • The minimum-valued element fromself.

  • A new array of minimum-valued elements fromself.

Does not modifyself.

With no block given, each element inself must respond to method<=> with a numeric.

With no argument and no block, returns the element inself having the minimum value per method<=>:

[1,0,3,2].min# => 0

With non-negative numeric argumentcount and no block, returns a new array with at mostcount elements, in ascending order, per method<=>:

[1,0,3,2].min(3)# => [0, 1, 2][1,0,3,2].min(3.0)# => [0, 1, 2][1,0,3,2].min(9)# => [0, 1, 2, 3][1,0,3,2].min(0)# => []

With a block given, the block must return a numeric.

With a block and no argument, calls the blockself.size - 1 times to compare elements; returns the element having the minimum value per the block:

['0','','000','00'].min {|a,b|a.size<=>b.size }# => ""

With non-negative numeric argumentcount and a block, returns a new array with at mostcount elements, in ascending order, per the block:

['0','','000','00'].min(2) {|a,b|a.size<=>b.size }# => ["", "0"]

Related: seeMethods for Fetching.

Source
static VALUErb_ary_minmax(VALUE ary){    if (rb_block_given_p()) {        return rb_call_super(0, NULL);    }    return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));}

Returns a 2-element array containing the minimum-valued and maximum-valued elements fromself; does not modifyself.

With no block given, the minimum and maximum values are determined using method<=>:

[1,0,3,2].minmax# => [0, 3]

With a block given, the block must return a numeric; the block is calledself.size - 1 times to compare elements; returns the elements having the minimum and maximum values per the block:

['0','','000','00'].minmax {|a,b|a.size<=>b.size }# => ["", "000"]

Related: seeMethods for Fetching.

Source
static VALUErb_ary_none_p(int argc, VALUE *argv, VALUE ary){    long i, len = RARRAY_LEN(ary);    rb_check_arity(argc, 0, 1);    if (!len) return Qtrue;    if (argc) {        if (rb_block_given_p()) {            rb_warn("given block not used");        }        for (i = 0; i < RARRAY_LEN(ary); ++i) {            if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;        }    }    else if (!rb_block_given_p()) {        for (i = 0; i < len; ++i) {            if (RTEST(RARRAY_AREF(ary, i))) return Qfalse;        }    }    else {        for (i = 0; i < RARRAY_LEN(ary); ++i) {            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;        }    }    return Qtrue;}

Returnstrue if no element ofself meets a given criterion,false otherwise.

With no block given and no argument, returnstrue ifself has no truthy elements,false otherwise:

[nil,false].none?# => true[nil,0,false].none?# => false[].none?# => true

With argumentobject given, returnsfalse if for any elementelement,object === element;true otherwise:

['food','drink'].none?(/bar/)# => true['food','drink'].none?(/foo/)# => false[].none?(/foo/)# => true[0,1,2].none?(3)# => true[0,1,2].none?(1)# => false

With a block given, calls the block with each element inself; returnstrue if the block returns no truthy value,false otherwise:

[0,1,2].none? {|element|element>3 }# => true[0,1,2].none? {|element|element>1 }# => false

Related: seeMethods for Querying.

Source
static VALUErb_ary_one_p(int argc, VALUE *argv, VALUE ary){    long i, len = RARRAY_LEN(ary);    VALUE result = Qfalse;    rb_check_arity(argc, 0, 1);    if (!len) return Qfalse;    if (argc) {        if (rb_block_given_p()) {            rb_warn("given block not used");        }        for (i = 0; i < RARRAY_LEN(ary); ++i) {            if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) {                if (result) return Qfalse;                result = Qtrue;            }        }    }    else if (!rb_block_given_p()) {        for (i = 0; i < len; ++i) {            if (RTEST(RARRAY_AREF(ary, i))) {                if (result) return Qfalse;                result = Qtrue;            }        }    }    else {        for (i = 0; i < RARRAY_LEN(ary); ++i) {            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {                if (result) return Qfalse;                result = Qtrue;            }        }    }    return result;}

Returnstrue if exactly one element ofself meets a given criterion.

With no block given and no argument, returnstrue ifself has exactly one truthy element,false otherwise:

[nil,0].one?# => true[0,0].one?# => false[nil,nil].one?# => false[].one?# => false

With a block given, calls the block with each element inself; returnstrue if the block a truthy value for exactly one element,false otherwise:

[0,1,2].one? {|element|element>0 }# => false[0,1,2].one? {|element|element>1 }# => true[0,1,2].one? {|element|element>2 }# => false

With argumentobject given, returnstrue if for exactly one elementelement,object === element;false otherwise:

[0,1,2].one?(0)# => true[0,0,1].one?(0)# => false[1,1,2].one?(0)# => false['food','drink'].one?(/bar/)# => false['food','drink'].one?(/foo/)# => true[].one?(/foo/)# => false

Related: seeMethods for Querying.

Source
# File pack.rb, line 7defpack(fmt,buffer:nil)Primitive.pack_pack(fmt,buffer)end

Formats each element inself into a binary string; returns that string. SeePacked Data.

Source
static VALUErb_ary_permutation(int argc, VALUE *argv, VALUE ary){    long r, n, i;    n = RARRAY_LEN(ary);                  /* Array length */    RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size);   /* Return enumerator if no block */    r = n;    if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0]))        r = NUM2LONG(argv[0]);            /* Permutation size from argument */    if (r < 0 || n < r) {        /* no permutations: yield nothing */    }    else if (r == 0) { /* exactly one permutation: the zero-length array */        rb_yield(rb_ary_new2(0));    }    else if (r == 1) { /* this is a special, easy case */        for (i = 0; i < RARRAY_LEN(ary); i++) {            rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));        }    }    else {             /* this is the general case */        volatile VALUE t0;        long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));        char *used = (char*)(p + r);        VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */        RBASIC_CLEAR_CLASS(ary0);        MEMZERO(used, char, n); /* initialize array */        permute0(n, r, p, used, ary0); /* compute and yield permutations */        ALLOCV_END(t0);        RBASIC_SET_CLASS_RAW(ary0, rb_cArray);    }    return ary;}

Iterates over permutations of the elements ofself; the order of permutations is indeterminate.

With a block and an in-range positive integer argumentcount (0 < count <= self.size) given, calls the block with each permutation ofself of sizecount; returnsself:

a = [0,1,2]perms = []a.permutation(1) {|perm|perms.push(perm) }perms# => [[0], [1], [2]]perms = []a.permutation(2) {|perm|perms.push(perm) }perms# => [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]]perms = []a.permutation(3) {|perm|perms.push(perm) }perms# => [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]

Whencount is zero, calls the block once with a new empty array:

perms = []a.permutation(0) {|perm|perms.push(perm) }perms# => [[]]

Whencount is out of range (negative or larger thanself.size), does not call the block:

a.permutation(-1) {|permutation|fail'Cannot happen' }a.permutation(4) {|permutation|fail'Cannot happen' }

With no block given, returns a newEnumerator.

Related:Methods for Iterating.

Source
static VALUErb_ary_pop_m(int argc, VALUE *argv, VALUE ary){    VALUE result;    if (argc == 0) {        return rb_ary_pop(ary);    }    rb_ary_modify_check(ary);    result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);    ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));    ary_verify(ary);    return result;}

Removes and returns trailing elements ofself.

With no argument given, removes and returns the last element, if available; otherwise returnsnil:

a = [:foo,'bar',2]a.pop# => 2a# => [:foo, "bar"][].pop# => nil

With non-negative integer argumentcount given, returns a new array containing the trailingcount elements ofself, as available:

a = [:foo,'bar',2]a.pop(2)# => ["bar", 2]a# => [:foo]a = [:foo,'bar',2]a.pop(50)# => [:foo, "bar", 2]a# => []

Related:Array#push; see alsoMethods for Deleting.

Prepends the givenobjects toself:

a = [:foo,'bar',2]a.unshift(:bam,:bat)# => [:bam, :bat, :foo, "bar", 2]

Related:Array#shift; see alsoMethods for Assigning.

Alias for:unshift
Source
static VALUErb_ary_product(int argc, VALUE *argv, VALUE ary){    int n = argc+1;    /* How many arrays we're operating on */    volatile VALUE t0 = rb_ary_hidden_new(n);    volatile VALUE t1 = Qundef;    VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */    int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */    VALUE result = Qnil;      /* The array we'll be returning, when no block given */    long i,j;    long resultlen = 1;    RBASIC_CLEAR_CLASS(t0);    /* initialize the arrays of arrays */    ARY_SET_LEN(t0, n);    arrays[0] = ary;    for (i = 1; i < n; i++) arrays[i] = Qnil;    for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);    /* initialize the counters for the arrays */    for (i = 0; i < n; i++) counters[i] = 0;    /* Otherwise, allocate and fill in an array of results */    if (rb_block_given_p()) {        /* Make defensive copies of arrays; exit if any is empty */        for (i = 0; i < n; i++) {            if (RARRAY_LEN(arrays[i]) == 0) goto done;            arrays[i] = ary_make_shared_copy(arrays[i]);        }    }    else {        /* Compute the length of the result array; return [] if any is empty */        for (i = 0; i < n; i++) {            long k = RARRAY_LEN(arrays[i]);            if (k == 0) {                result = rb_ary_new2(0);                goto done;            }            if (MUL_OVERFLOW_LONG_P(resultlen, k))                rb_raise(rb_eRangeError, "too big to product");            resultlen *= k;        }        result = rb_ary_new2(resultlen);    }    for (;;) {        int m;        /* fill in one subarray */        VALUE subarray = rb_ary_new2(n);        for (j = 0; j < n; j++) {            rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));        }        /* put it on the result array */        if (NIL_P(result)) {            FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);            rb_yield(subarray);            if (!FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {                rb_raise(rb_eRuntimeError, "product reentered");            }            else {                FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);            }        }        else {            rb_ary_push(result, subarray);        }        /*         * Increment the last counter.  If it overflows, reset to 0         * and increment the one before it.         */        m = n-1;        counters[m]++;        while (counters[m] == RARRAY_LEN(arrays[m])) {            counters[m] = 0;            /* If the first counter overflows, we are done */            if (--m < 0) goto done;            counters[m]++;        }    }done:    ALLOCV_END(t1);    return NIL_P(result) ? ary : result;}

Computes all combinations of elements from all the arrays, including bothself andother_arrays:

  • The number of combinations is the product of the sizes of all the arrays, including bothself andother_arrays.

  • The order of the returned combinations is indeterminate.

With no block given, returns the combinations as an array of arrays:

p = [0,1].product([2,3])# => [[0, 2], [0, 3], [1, 2], [1, 3]]p.size# => 4p = [0,1].product([2,3], [4,5])# => [[0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3,...p.size# => 8

Ifself or any argument is empty, returns an empty array:

[].product([2,3], [4,5])# => [][0,1].product([2,3], [])# => []

If no argument is given, returns an array of 1-element arrays, each containing an element ofself:

a.product# => [[0], [1], [2]]

With a block given, calls the block with each combination; returnsself:

p = [][0,1].product([2,3]) {|combination|p.push(combination) }p# => [[0, 2], [0, 3], [1, 2], [1, 3]]

Ifself or any argument is empty, does not call the block:

[].product([2,3], [4,5]) {|combination|fail'Cannot happen' }# => [][0,1].product([2,3], []) {|combination|fail'Cannot happen' }# => [0, 1]

If no argument is given, calls the block with each element ofself as a 1-element array:

p = [][0,1].product {|combination|p.push(combination) }p# => [[0], [1]]

Related: seeMethods for Combining.

Source
static VALUErb_ary_push_m(int argc, VALUE *argv, VALUE ary){    return rb_ary_cat(ary, argv, argc);}

Appends each argument inobjects toself; returnsself:

a = [:foo,'bar',2]# => [:foo, "bar", 2]a.push(:baz,:bat)# => [:foo, "bar", 2, :baz, :bat]

Appends each argument as a single element, even if it is another array:

a = [:foo,'bar',2]# => [:foo, "bar", 2]a.push([:baz,:bat], [:bam,:bad])# => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]

Related: seeMethods for Assigning.

Also aliased as:append
Source
VALUErb_ary_rassoc(VALUE ary, VALUE value){    long i;    VALUE v;    for (i = 0; i < RARRAY_LEN(ary); ++i) {        v = rb_check_array_type(RARRAY_AREF(ary, i));        if (RB_TYPE_P(v, T_ARRAY) &&            RARRAY_LEN(v) > 1 &&            rb_equal(RARRAY_AREF(v, 1), value))            return v;    }    return Qnil;}

Returns the first elementele inself such thatele is an array andele[1] == object:

a = [{foo:0}, [2,4], [4,5,6], [4,5]]a.rassoc(4)# => [2, 4]a.rassoc(5)# => [4, 5, 6]

Returnsnil if no such element is found.

Related:Array#assoc; see alsoMethods for Fetching.

Source
static VALUErb_ary_reject(VALUE ary){    VALUE rejected_ary;    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    rejected_ary = rb_ary_new();    ary_reject(ary, rejected_ary);    return rejected_ary;}

With a block given, returns a new array whose elements are all those fromself for which the block returnsfalse ornil:

a = [:foo,'bar',2,'bat']a1 =a.reject {|element|element.to_s.start_with?('b') }a1# => [:foo, 2]

With no block given, returns a newEnumerator.

Related:Methods for Fetching.

Source
static VALUErb_ary_reject_bang(VALUE ary){    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    rb_ary_modify(ary);    return ary_reject_bang(ary);}

With a block given, calls the block with each element ofself; removes each element for which the block returns a truthy value.

Returnsself if any elements removed:

a = [:foo,'bar',2,'bat']a.reject! {|element|element.to_s.start_with?('b') }# => [:foo, 2]

Returnsnil if no elements removed.

With no block given, returns a newEnumerator.

Related: seeMethods for Deleting.

Source
static VALUErb_ary_repeated_combination(VALUE ary, VALUE num){    long n, i, len;    n = NUM2LONG(num);                 /* Combination size from argument */    RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size);   /* Return enumerator if no block */    len = RARRAY_LEN(ary);    if (n < 0) {        /* yield nothing */    }    else if (n == 0) {        rb_yield(rb_ary_new2(0));    }    else if (n == 1) {        for (i = 0; i < RARRAY_LEN(ary); i++) {            rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));        }    }    else if (len == 0) {        /* yield nothing */    }    else {        volatile VALUE t0;        long *p = ALLOCV_N(long, t0, n);        VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */        RBASIC_CLEAR_CLASS(ary0);        rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */        ALLOCV_END(t0);        RBASIC_SET_CLASS_RAW(ary0, rb_cArray);    }    return ary;}

With a block given, calls the block with each repeated combination of lengthsize of the elements ofself; each combination is an array; returnsself. The order of the combinations is indeterminate.

If a positive integer argumentsize is given, calls the block with eachsize-tuple repeated combination of the elements ofself. The number of combinations is(size+1)(size+2)/2.

Examples:

  • size is 1:

    c = [][0,1,2].repeated_combination(1) {|combination|c.push(combination) }c# => [[0], [1], [2]]
  • size is 2:

    c = [][0,1,2].repeated_combination(2) {|combination|c.push(combination) }c# => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]

Ifsize is zero, calls the block once with an empty array.

Ifsize is negative, does not call the block:

[0,1,2].repeated_combination(-1) {|combination|fail'Cannot happen' }

With no block given, returns a newEnumerator.

Related: seeMethods for Combining.

Source
static VALUErb_ary_repeated_permutation(VALUE ary, VALUE num){    long r, n, i;    n = RARRAY_LEN(ary);                  /* Array length */    RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size);      /* Return Enumerator if no block */    r = NUM2LONG(num);                    /* Permutation size from argument */    if (r < 0) {        /* no permutations: yield nothing */    }    else if (r == 0) { /* exactly one permutation: the zero-length array */        rb_yield(rb_ary_new2(0));    }    else if (r == 1) { /* this is a special, easy case */        for (i = 0; i < RARRAY_LEN(ary); i++) {            rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));        }    }    else {             /* this is the general case */        volatile VALUE t0;        long *p = ALLOCV_N(long, t0, r);        VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */        RBASIC_CLEAR_CLASS(ary0);        rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */        ALLOCV_END(t0);        RBASIC_SET_CLASS_RAW(ary0, rb_cArray);    }    return ary;}

With a block given, calls the block with each repeated permutation of lengthsize of the elements ofself; each permutation is an array; returnsself. The order of the permutations is indeterminate.

If a positive integer argumentsize is given, calls the block with eachsize-tuple repeated permutation of the elements ofself. The number of permutations isself.size**size.

Examples:

  • size is 1:

    p = [][0,1,2].repeated_permutation(1) {|permutation|p.push(permutation) }p# => [[0], [1], [2]]
  • size is 2:

    p = [][0,1,2].repeated_permutation(2) {|permutation|p.push(permutation) }p# => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]

Ifsize is zero, calls the block once with an empty array.

Ifsize is negative, does not call the block:

[0,1,2].repeated_permutation(-1) {|permutation|fail'Cannot happen' }

With no block given, returns a newEnumerator.

Related: seeMethods for Combining.

Replaces the elements ofself with the elements ofother_array, which must be anarray-convertible object; returnsself:

a = ['a','b','c']# => ["a", "b", "c"]a.replace(['d','e'])# => ["d", "e"]

Related: seeMethods for Assigning.

Alias for:initialize_copy
Source
static VALUErb_ary_reverse_m(VALUE ary){    long len = RARRAY_LEN(ary);    VALUE dup = rb_ary_new2(len);    if (len > 0) {        const VALUE *p1 = RARRAY_CONST_PTR(ary);        VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;        do *p2-- = *p1++; while (--len > 0);    }    ARY_SET_LEN(dup, RARRAY_LEN(ary));    return dup;}

Returns a new array containing the elements ofself in reverse order:

[0,1,2].reverse# => [2, 1, 0]

Related: seeMethods for Combining.

Source
static VALUErb_ary_reverse_bang(VALUE ary){    return rb_ary_reverse(ary);}

Reverses the order of the elements ofself; returnsself:

a = [0,1,2]a.reverse!# => [2, 1, 0]a# => [2, 1, 0]

Related: seeMethods for Assigning.

Source
static VALUErb_ary_reverse_each(VALUE ary){    long len;    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    len = RARRAY_LEN(ary);    while (len--) {        long nlen;        rb_yield(RARRAY_AREF(ary, len));        nlen = RARRAY_LEN(ary);        if (nlen < len) {            len = nlen;        }    }    return ary;}

When a block given, iterates backwards over the elements ofself, passing, in reverse order, each element to the block; returnsself:

a = [][0,1,2].reverse_each {|element|a.push(element) }a# => [2, 1, 0]

Allows the array to be modified during iteration:

a = ['a','b','c']a.reverse_each {|element|a.clearifelement.start_with?('b') }a# => []

When no block given, returns a newEnumerator.

Related: seeMethods for Iterating.

Source
static VALUErb_ary_rindex(int argc, VALUE *argv, VALUE ary){    VALUE val;    long i = RARRAY_LEN(ary), len;    if (argc == 0) {        RETURN_ENUMERATOR(ary, 0, 0);        while (i--) {            if (RTEST(rb_yield(RARRAY_AREF(ary, i))))                return LONG2NUM(i);            if (i > (len = RARRAY_LEN(ary))) {                i = len;            }        }        return Qnil;    }    rb_check_arity(argc, 0, 1);    val = argv[0];    if (rb_block_given_p())        rb_warn("given block not used");    while (i--) {        VALUE e = RARRAY_AREF(ary, i);        if (rb_equal(e, val)) {            return LONG2NUM(i);        }        if (i > RARRAY_LEN(ary)) {            break;        }    }    return Qnil;}

Returns the index of the last element for whichobject == element.

With argumentobject given, returns the index of the last such element found:

a = [:foo,'bar',2,'bar']a.rindex('bar')# => 3

Returnsnil if no such object found.

With a block given, calls the block with each successive element; returns the index of the last element for which the block returns a truthy value:

a = [:foo,'bar',2,'bar']a.rindex {|element|element=='bar' }# => 3

Returnsnil if the block never returns a truthy value.

When neither an argument nor a block is given, returns a newEnumerator.

Related: seeMethods for Querying.

Source
static VALUErb_ary_rotate_m(int argc, VALUE *argv, VALUE ary){    VALUE rotated;    const VALUE *ptr;    long len;    long cnt = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);    len = RARRAY_LEN(ary);    rotated = rb_ary_new2(len);    if (len > 0) {        cnt = rotate_count(cnt, len);        ptr = RARRAY_CONST_PTR(ary);        len -= cnt;        ary_memcpy(rotated, 0, len, ptr + cnt);        ary_memcpy(rotated, len, cnt, ptr);    }    ARY_SET_LEN(rotated, RARRAY_LEN(ary));    return rotated;}

Returns a new array formed fromself with elements rotated from one end to the other.

With non-negative numericcount, rotates elements from the beginning to the end:

[0,1,2,3].rotate(2)# => [2, 3, 0, 1][0,1,2,3].rotate(2.1)# => [2, 3, 0, 1]

Ifcount is large, usescount % array.size as the count:

[0,1,2,3].rotate(22)# => [2, 3, 0, 1]

With acount of zero, rotates no elements:

[0,1,2,3].rotate(0)# => [0, 1, 2, 3]

With negative numericcount, rotates in the opposite direction, from the end to the beginning:

[0,1,2,3].rotate(-1)# => [3, 0, 1, 2]

Ifcount is small (far from zero), usescount % array.size as the count:

[0,1,2,3].rotate(-21)# => [3, 0, 1, 2]

Related: seeMethods for Fetching.

Source
static VALUErb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary){    long n = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);    rb_ary_rotate(ary, n);    return ary;}

Rotatesself in place by moving elements from one end to the other; returnsself.

With non-negative numericcount, rotatescount elements from the beginning to the end:

[0,1,2,3].rotate!(2)# => [2, 3, 0, 1][0,1,2,3].rotate!(2.1)# => [2, 3, 0, 1]

Ifcount is large, usescount % array.size as the count:

[0,1,2,3].rotate!(21)# => [1, 2, 3, 0]

Ifcount is zero, rotates no elements:

[0,1,2,3].rotate!(0)# => [0, 1, 2, 3]

With a negative numericcount, rotates in the opposite direction, from end to beginning:

[0,1,2,3].rotate!(-1)# => [3, 0, 1, 2]

Ifcount is small (far from zero), usescount % array.size as the count:

[0,1,2,3].rotate!(-21)# => [3, 0, 1, 2]

Related: seeMethods for Assigning.

Source
# File array.rb, line 95defsample(n = (ary =false),random:Random)ifPrimitive.mandatory_only?# Primitive.cexpr! %{ rb_ary_sample(self, rb_cRandom, Qfalse, Qfalse) }Primitive.ary_sample0else# Primitive.cexpr! %{ rb_ary_sample(self, random, n, ary) }Primitive.ary_sample(random,n,ary)endend

Returns random elements fromself, as selected by the object given by the keyword argumentrandom.

With no argumentcount given, returns one random element fromself:

a = [0,1,2,3,4,5,6,7,8,9]a.sample# => 3a.sample# => 8

Returnsnil ifself is empty:

[].sample# => nil

With a non-negative numeric argumentcount given, returns a new array containingcount random elements fromself:

a.sample(3)# => [8, 9, 2]a.sample(6)# => [9, 6, 0, 3, 1, 4]

The order of the result array is unrelated to the order ofself.

Returns a new empty array ifself is empty:

[].sample(4)# => []

May return duplicates inself:

a = [1,1,1,2,2,3]a.sample(a.size)# => [1, 1, 3, 2, 1, 2]

Returns no more thana.size elements (because no new duplicates are introduced):

a.sample(50)# => [6, 4, 1, 8, 5, 9, 0, 2, 3, 7]

The object given with the keyword argumentrandom is used as the random number generator:

a = [1,2,3,4,5,6,7,8,9,10]a.sample(random:Random.new(1))# => 6a.sample(4,random:Random.new(1))# => [6, 10, 9, 2]

Related: seeMethods for Fetching.

Source
static VALUErb_ary_select(VALUE ary){    VALUE result;    long i;    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    result = rb_ary_new2(RARRAY_LEN(ary));    for (i = 0; i < RARRAY_LEN(ary); i++) {        if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {            rb_ary_push(result, rb_ary_elt(ary, i));        }    }    return result;}

With a block given, calls the block with each element ofself; returns a new array containing those elements ofself for which the block returns a truthy value:

a = [:foo,'bar',2,:bam]a.select {|element|element.to_s.start_with?('b') }# => ["bar", :bam]

With no block given, returns a newEnumerator.

Related: seeMethods for Fetching.

Also aliased as:filter, filter
Source
static VALUErb_ary_select_bang(VALUE ary){    struct select_bang_arg args;    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    rb_ary_modify(ary);    args.ary = ary;    args.len[0] = args.len[1] = 0;    return rb_ensure(select_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);}

With a block given, calls the block with each element ofself; removes fromself those elements for which the block returnsfalse ornil.

Returnsself if any elements were removed:

a = [:foo,'bar',2,:bam]a.select! {|element|element.to_s.start_with?('b') }# => ["bar", :bam]

Returnsnil if no elements were removed.

With no block given, returns a newEnumerator.

Related: seeMethods for Deleting.

Also aliased as:filter!
Source
# File lib/shellwords.rb, line 251defshelljoinShellwords.join(self)end

Builds a command line string from an argument listarray joining all elements escaped for the Bourne shell and separated by a space.

SeeShellwords.shelljoin for details.

Source
static VALUErb_ary_shift_m(int argc, VALUE *argv, VALUE ary){    VALUE result;    long n;    if (argc == 0) {        return rb_ary_shift(ary);    }    rb_ary_modify_check(ary);    result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);    n = RARRAY_LEN(result);    rb_ary_behead(ary,n);    return result;}

Removes and returns leading elements fromself.

With no argument, removes and returns one element, if available, ornil otherwise:

a = [0,1,2,3]a.shift# => 0a# => [1, 2, 3][].shift# => nil

With non-negative numeric argumentcount given, removes and returns the firstcount elements:

a = [0,1,2,3]a.shift(2)# => [0, 1]a# => [2, 3]a.shift(1.1)# => [2]a# => [3]a.shift(0)# => []a# => [3]

Ifcount is large, removes and returns all elements:

a = [0,1,2,3]a.shift(50)# => [0, 1, 2, 3]a# => []

Ifself is empty, returns a new empty array.

Related: seeMethods for Deleting.

Source
# File array.rb, line 45defshuffle(random:Random)Primitive.rb_ary_shuffle(random)end

Returns a new array containing all elements fromself in a random order, as selected by the object given by the keyword argumentrandom:

a =            [0,1,2,3,4,5,6,7,8,9]a.shuffle# => [0, 8, 1, 9, 6, 3, 4, 7, 2, 5]a.shuffle# => [8, 9, 0, 5, 1, 2, 6, 4, 7, 3]

Duplicate elements are included:

a =            [0,1,0,1,0,1,0,1,0,1]a.shuffle# => [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]a.shuffle# => [1, 1, 0, 0, 0, 1, 1, 0, 0, 1]

The object given with the keyword argumentrandom is used as the random number generator.

Related: seeMethods for Fetching.

Source
# File array.rb, line 22defshuffle!(random:Random)Primitive.rb_ary_shuffle_bang(random)end

Shuffles all elements inself into a random order, as selected by the object given by the keyword argumentrandom. Returnsself:

a =             [0,1,2,3,4,5,6,7,8,9]a.shuffle!# => [5, 3, 8, 7, 6, 1, 9, 4, 2, 0]a.shuffle!# => [9, 4, 0, 6, 2, 8, 1, 5, 3, 7]

Duplicate elements are included:

a =             [0,1,0,1,0,1,0,1,0,1]a.shuffle!# => [1, 0, 0, 1, 1, 0, 1, 0, 0, 1]a.shuffle!# => [0, 1, 0, 1, 1, 0, 1, 0, 1, 0]

The object given with the keyword argumentrandom is used as the random number generator.

Related: seeMethods for Assigning.

Returns the count of elements inself:

[0,1,2].length# => 3[].length# => 0

Related: seeMethods for Querying.

Alias for:length

Returns elements fromself; does not modifyself.

In brief:

a = [:foo,'bar',2]# Single argument index: returns one element.a[0]# => :foo          # Zero-based index.a[-1]# => 2             # Negative index counts backwards from end.# Arguments start and length: returns an array.a[1,2]# => ["bar", 2]a[-2,2]# => ["bar", 2]    # Negative start counts backwards from end.# Single argument range: returns an array.a[0..1]# => [:foo, "bar"]a[0..-2]# => [:foo, "bar"] # Negative range-begin counts backwards from end.a[-2..2]# => ["bar", 2]    # Negative range-end counts backwards from end.

When a single integer argumentindex is given, returns the element at offsetindex:

a = [:foo,'bar',2]a[0]# => :fooa[2]# => 2a# => [:foo, "bar", 2]

Ifindex is negative, counts backwards from the end ofself:

a = [:foo,'bar',2]a[-1]# => 2a[-2]# => "bar"

Ifindex is out of range, returnsnil.

When twoInteger argumentsstart andlength are given, returns a new array of sizelength containing successive elements beginning at offsetstart:

a = [:foo,'bar',2]a[0,2]# => [:foo, "bar"]a[1,2]# => ["bar", 2]

Ifstart + length is greater thanself.length, returns all elements from offsetstart to the end:

a = [:foo,'bar',2]a[0,4]# => [:foo, "bar", 2]a[1,3]# => ["bar", 2]a[2,2]# => [2]

Ifstart == self.size andlength >= 0, returns a new empty array.

Iflength is negative, returnsnil.

When a singleRange argumentrange is given, treatsrange.min asstart above andrange.size aslength above:

a = [:foo,'bar',2]a[0..1]# => [:foo, "bar"]a[1..2]# => ["bar", 2]

Special case: Ifrange.start == a.size, returns a new empty array.

Ifrange.end is negative, calculates the end index from the end:

a = [:foo,'bar',2]a[0..-1]# => [:foo, "bar", 2]a[0..-2]# => [:foo, "bar"]a[0..-3]# => [:foo]

Ifrange.start is negative, calculates the start index from the end:

a = [:foo,'bar',2]a[-1..2]# => [2]a[-2..2]# => ["bar", 2]a[-3..2]# => [:foo, "bar", 2]

Ifrange.start is larger than the array size, returnsnil.

a = [:foo,'bar',2]a[4..1]# => nila[4..0]# => nila[4..-1]# => nil

When a singleEnumerator::ArithmeticSequence argumentaseq is given, returns an array of elements corresponding to the indexes produced by the sequence.

a = ['--','data1','--','data2','--','data3']a[(1..).step(2)]# => ["data1", "data2", "data3"]

Unlike slicing with range, if the start or the end of the arithmetic sequence is larger than array size, throwsRangeError.

a = ['--','data1','--','data2','--','data3']a[(1..11).step(2)]# RangeError (((1..11).step(2)) out of range)a[(7..).step(2)]# RangeError (((7..).step(2)) out of range)

If given a single argument, and its type is not one of the listed, tries to convert it toInteger, and raises if it is impossible:

a = [:foo,'bar',2]# Raises TypeError (no implicit conversion of Symbol into Integer):a[:foo]

Related: seeMethods for Fetching.

Alias for:[]
Source
static VALUErb_ary_slice_bang(int argc, VALUE *argv, VALUE ary){    VALUE arg1;    long pos, len;    rb_ary_modify_check(ary);    rb_check_arity(argc, 1, 2);    arg1 = argv[0];    if (argc == 2) {        pos = NUM2LONG(argv[0]);        len = NUM2LONG(argv[1]);        return ary_slice_bang_by_rb_ary_splice(ary, pos, len);    }    if (!FIXNUM_P(arg1)) {        switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {          case Qtrue:            /* valid range */            return ary_slice_bang_by_rb_ary_splice(ary, pos, len);          case Qnil:            /* invalid range */            return Qnil;          default:            /* not a range */            break;        }    }    return rb_ary_delete_at(ary, NUM2LONG(arg1));}

Removes and returns elements fromself.

With numeric argumentindex given, removes and returns the element at offsetindex:

a = ['a','b','c','d']a.slice!(2)# => "c"a# => ["a", "b", "d"]a.slice!(2.1)# => "d"a# => ["a", "b"]

Ifindex is negative, counts backwards from the end ofself:

a = ['a','b','c','d']a.slice!(-2)# => "c"a# => ["a", "b", "d"]

Ifindex is out of range, returnsnil.

With numeric argumentsstart andlength given, removeslength elements fromself beginning at zero-based offsetstart; returns the removed objects in a new array:

a = ['a','b','c','d']a.slice!(1,2)# => ["b", "c"]a# => ["a", "d"]a.slice!(0.1,1.1)# => ["a"]a# => ["d"]

Ifstart is negative, counts backwards from the end ofself:

a = ['a','b','c','d']a.slice!(-2,1)# => ["c"]a# => ["a", "b", "d"]

Ifstart is out-of-range, returnsnil:

a = ['a','b','c','d']a.slice!(5,1)# => nila.slice!(-5,1)# => nil

Ifstart + length exceeds the array size, removes and returns all elements from offsetstart to the end:

a = ['a','b','c','d']a.slice!(2,50)# => ["c", "d"]a# => ["a", "b"]

Ifstart == a.size andlength is non-negative, returns a new empty array.

Iflength is negative, returnsnil.

WithRange argumentrange given, treatsrange.min asstart (as above) andrange.size aslength (as above):

a = ['a','b','c','d']a.slice!(1..2)# => ["b", "c"]a# => ["a", "d"]

Ifrange.start == a.size, returns a new empty array:

a = ['a','b','c','d']a.slice!(4..5)# => []

Ifrange.start is larger than the array size, returnsnil:

a = ['a','b','c','d']a.slice!(5..6)# => nil

Ifrange.start is negative, calculates the start index by counting backwards from the end ofself:

a = ['a','b','c','d']a.slice!(-2..2)# => ["c"]

Ifrange.end is negative, calculates the end index by counting backwards from the end ofself:

a = ['a','b','c','d']a.slice!(0..-2)# => ["a", "b", "c"]

Related: seeMethods for Deleting.

Source
VALUErb_ary_sort(VALUE ary){    ary = rb_ary_dup(ary);    rb_ary_sort_bang(ary);    return ary;}

Returns a new array containing the elements ofself, sorted.

With no block given, compares elements using operator<=> (seeObject#<=>):

[0,2,3,1].sort# => [0, 1, 2, 3]

With a block given, calls the block with each combination of pairs of elements fromself; for each paira andb, the block should return a numeric:

  • Negative whenb is to followa.

  • Zero whena andb are equivalent.

  • Positive whena is to followb.

Example:

a = [3,2,0,1]a.sort {|a,b|a<=>b }# => [0, 1, 2, 3]a.sort {|a,b|b<=>a }# => [3, 2, 1, 0]

When the block returns zero, the order fora andb is indeterminate, and may be unstable.

See an example inNumeric#nonzero? for the idiom to sort more complex structure.

Related: seeMethods for Fetching.

Source
VALUErb_ary_sort_bang(VALUE ary){    rb_ary_modify(ary);    RUBY_ASSERT(!ARY_SHARED_P(ary));    if (RARRAY_LEN(ary) > 1) {        VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */        struct ary_sort_data data;        long len = RARRAY_LEN(ary);        RBASIC_CLEAR_CLASS(tmp);        data.ary = tmp;        data.receiver = ary;        RARRAY_PTR_USE(tmp, ptr, {            ruby_qsort(ptr, len, sizeof(VALUE),                       rb_block_given_p()?sort_1:sort_2, &data);        }); /* WB: no new reference */        rb_ary_modify(ary);        if (ARY_EMBED_P(tmp)) {            if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */                rb_ary_unshare(ary);                FL_SET_EMBED(ary);            }            if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) {                ary_resize_capa(ary, ARY_EMBED_LEN(tmp));            }            ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));            ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));        }        else {            if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {                FL_UNSET_SHARED(ary);                ARY_SET_CAPA(ary, RARRAY_LEN(tmp));            }            else {                RUBY_ASSERT(!ARY_SHARED_P(tmp));                if (ARY_EMBED_P(ary)) {                    FL_UNSET_EMBED(ary);                }                else if (ARY_SHARED_P(ary)) {                    /* ary might be destructively operated in the given block */                    rb_ary_unshare(ary);                }                else {                    ary_heap_free(ary);                }                ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));                ARY_SET_HEAP_LEN(ary, len);                ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));            }            /* tmp was lost ownership for the ptr */            FL_SET_EMBED(tmp);            ARY_SET_EMBED_LEN(tmp, 0);            OBJ_FREEZE(tmp);        }        /* tmp will be GC'ed. */        RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */    }    ary_verify(ary);    return ary;}

LikeArray#sort, but returnsself with its elements sorted in place.

Related: seeMethods for Assigning.

Source
static VALUErb_ary_sort_by_bang(VALUE ary){    VALUE sorted;    RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);    rb_ary_modify(ary);    if (RARRAY_LEN(ary) > 1) {        sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);        rb_ary_replace(ary, sorted);    }    return ary;}

With a block given, sorts the elements ofself in place; returns self.

Calls the block with each successive element; sorts elements based on the values returned from the block:

a = ['aaaa','bbb','cc','d']a.sort_by! {|element|element.size }a# => ["d", "cc", "bbb", "aaaa"]

For duplicate values returned by the block, the ordering is indeterminate, and may be unstable.

With no block given, returns a newEnumerator.

Related: seeMethods for Assigning.

Source
static VALUErb_ary_sum(int argc, VALUE *argv, VALUE ary){    VALUE e, v, r;    long i, n;    int block_given;    v = (rb_check_arity(argc, 0, 1) ? argv[0] : LONG2FIX(0));    block_given = rb_block_given_p();    if (RARRAY_LEN(ary) == 0)        return v;    n = 0;    r = Qundef;    if (!FIXNUM_P(v) && !RB_BIGNUM_TYPE_P(v) && !RB_TYPE_P(v, T_RATIONAL)) {        i = 0;        goto init_is_a_value;    }    for (i = 0; i < RARRAY_LEN(ary); i++) {        e = RARRAY_AREF(ary, i);        if (block_given)            e = rb_yield(e);        if (FIXNUM_P(e)) {            n += FIX2LONG(e); /* should not overflow long type */            if (!FIXABLE(n)) {                v = rb_big_plus(LONG2NUM(n), v);                n = 0;            }        }        else if (RB_BIGNUM_TYPE_P(e))            v = rb_big_plus(e, v);        else if (RB_TYPE_P(e, T_RATIONAL)) {            if (UNDEF_P(r))                r = e;            else                r = rb_rational_plus(r, e);        }        else            goto not_exact;    }    v = finish_exact_sum(n, r, v, argc!=0);    return v;  not_exact:    v = finish_exact_sum(n, r, v, i!=0);    if (RB_FLOAT_TYPE_P(e)) {        /*         * Kahan-Babuska balancing compensated summation algorithm         * See https://link.springer.com/article/10.1007/s00607-005-0139-x         */        double f, c;        double x, t;        f = NUM2DBL(v);        c = 0.0;        goto has_float_value;        for (; i < RARRAY_LEN(ary); i++) {            e = RARRAY_AREF(ary, i);            if (block_given)                e = rb_yield(e);            if (RB_FLOAT_TYPE_P(e))              has_float_value:                x = RFLOAT_VALUE(e);            else if (FIXNUM_P(e))                x = FIX2LONG(e);            else if (RB_BIGNUM_TYPE_P(e))                x = rb_big2dbl(e);            else if (RB_TYPE_P(e, T_RATIONAL))                x = rb_num2dbl(e);            else                goto not_float;            if (isnan(f)) continue;            if (isnan(x)) {                f = x;                continue;            }            if (isinf(x)) {                if (isinf(f) && signbit(x) != signbit(f))                    f = NAN;                else                    f = x;                continue;            }            if (isinf(f)) continue;            t = f + x;            if (fabs(f) >= fabs(x))                c += ((f - t) + x);            else                c += ((x - t) + f);            f = t;        }        f += c;        return DBL2NUM(f);      not_float:        v = DBL2NUM(f);    }    goto has_some_value;    init_is_a_value:    for (; i < RARRAY_LEN(ary); i++) {        e = RARRAY_AREF(ary, i);        if (block_given)            e = rb_yield(e);      has_some_value:        v = rb_funcall(v, idPLUS, 1, e);    }    return v;}

With no block given, returns the sum ofinit and all elements ofself; for arrayarray and valueinit, equivalent to:

sum =initarray.each {|element|sum+=element }sum

For example,[e0, e1, e2].sum returnsinit + e0 + e1 + e2.

Examples:

[0,1,2,3].sum# => 6[0,1,2,3].sum(100)# => 106['abc','def','ghi'].sum('jkl')# => "jklabcdefghi"[[:foo,:bar], ['foo','bar']].sum([2,3])# => [2, 3, :foo, :bar, "foo", "bar"]

Theinit value and elements need not be numeric, but must all be+-compatible:

# Raises TypeError: Array can't be coerced into Integer.[[:foo,:bar], ['foo','bar']].sum(2)

With a block given, calls the block with each element ofself; the block’s return value (instead of the element itself) is used as the addend:

['zero',1,:two].sum('Coerced and concatenated: ') {|element|element.to_s }# => "Coerced and concatenated: zero1two"

Notes:

Source
static VALUErb_ary_take(VALUE obj, VALUE n){    long len = NUM2LONG(n);    if (len < 0) {        rb_raise(rb_eArgError, "attempt to take negative size");    }    return rb_ary_subseq(obj, 0, len);}

Returns a new array containing the firstcount element ofself (as available);count must be a non-negative numeric; does not modifyself:

a = ['a','b','c','d']a.take(2)# => ["a", "b"]a.take(2.1)# => ["a", "b"]a.take(50)# => ["a", "b", "c", "d"]a.take(0)# => []

Related: seeMethods for Fetching.

Source
static VALUErb_ary_take_while(VALUE ary){    long i;    RETURN_ENUMERATOR(ary, 0, 0);    for (i = 0; i < RARRAY_LEN(ary); i++) {        if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;    }    return rb_ary_take(ary, LONG2FIX(i));}

With a block given, calls the block with each successive element ofself; stops iterating if the block returnsfalse ornil; returns a new array containing those elements for which the block returned a truthy value:

a = [0,1,2,3,4,5]a.take_while {|element|element<3 }# => [0, 1, 2]a.take_while {|element|true }# => [0, 1, 2, 3, 4, 5]a.take_while {|element|false }# => []

With no block given, returns a newEnumerator.

Does not modifyself.

Related: seeMethods for Fetching.

Source
static VALUErb_ary_to_a(VALUE ary){    if (rb_obj_class(ary) != rb_cArray) {        VALUE dup = rb_ary_new2(RARRAY_LEN(ary));        rb_ary_replace(dup, ary);        return dup;    }    return ary;}

Whenself is an instance of Array, returnsself.

Otherwise, returns a new array containing the elements ofself:

classMyArray<Array;endmy_a =MyArray.new(['foo','bar','two'])a =my_a.to_aa# => ["foo", "bar", "two"]a.class# => Array # Not MyArray.

Related: seeMethods for Converting.

Source
static VALUErb_ary_to_ary_m(VALUE ary){    return ary;}

Returnsself.

Source
static VALUErb_ary_to_h(VALUE ary){    long i;    VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary));    int block_given = rb_block_given_p();    for (i=0; i<RARRAY_LEN(ary); i++) {        const VALUE e = rb_ary_elt(ary, i);        const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;        const VALUE key_value_pair = rb_check_array_type(elt);        if (NIL_P(key_value_pair)) {            rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %ld (expected array)",                     rb_obj_class(elt), i);        }        if (RARRAY_LEN(key_value_pair) != 2) {            rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",                i, RARRAY_LEN(key_value_pair));        }        rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));    }    return hash;}

Returns a new hash formed fromself.

With no block given, each element ofself must be a 2-element sub-array; forms each sub-array into a key-value pair in the new hash:

a = [['foo','zero'], ['bar','one'], ['baz','two']]a.to_h# => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"}[].to_h# => {}

With a block given, the block must return a 2-element array; calls the block with each element ofself; forms each returned array into a key-value pair in the returned hash:

a = ['foo',:bar,1, [2,3], {baz:4}]a.to_h {|element| [element,element.class] }# => {"foo"=>String, :bar=>Symbol, 1=>Integer, [2, 3]=>Array, {:baz=>4}=>Hash}

Related: seeMethods for Converting.

Returns the new string formed by calling methodinspect on each array element:

a = [:foo,'bar',2]a.inspect# => "[:foo, \"bar\", 2]"

Related: seeMethods for Converting.

Alias for:inspect
Source
static VALUErb_ary_transpose(VALUE ary){    long elen = -1, alen, i, j;    VALUE tmp, result = 0;    alen = RARRAY_LEN(ary);    if (alen == 0) return rb_ary_dup(ary);    for (i=0; i<alen; i++) {        tmp = to_ary(rb_ary_elt(ary, i));        if (elen < 0) {         /* first element */            elen = RARRAY_LEN(tmp);            result = rb_ary_new2(elen);            for (j=0; j<elen; j++) {                rb_ary_store(result, j, rb_ary_new2(alen));            }        }        else if (elen != RARRAY_LEN(tmp)) {            rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",                     RARRAY_LEN(tmp), elen);        }        for (j=0; j<elen; j++) {            rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));        }    }    return result;}

Returns a new array that isself as atransposed matrix:

a = [[:a0,:a1], [:b0,:b1], [:c0,:c1]]a.transpose# => [[:a0, :b0, :c0], [:a1, :b1, :c1]]

The elements ofself must all be the same size.

Related: seeMethods for Converting.

Source
static VALUErb_ary_union_multi(int argc, VALUE *argv, VALUE ary){    int i;    long sum;    VALUE hash;    sum = RARRAY_LEN(ary);    for (i = 0; i < argc; i++) {        argv[i] = to_ary(argv[i]);        sum += RARRAY_LEN(argv[i]);    }    if (sum <= SMALL_ARRAY_LEN) {        VALUE ary_union = rb_ary_new();        rb_ary_union(ary_union, ary);        for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);        return ary_union;    }    hash = ary_make_hash(ary);    for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);    return rb_hash_values(hash);}

Returns a new array that is the union of the elements ofself and all given arraysother_arrays; items are compared usingeql?:

[0,1,2,3].union([4,5], [6,7])# => [0, 1, 2, 3, 4, 5, 6, 7]

Removes duplicates (preserving the first found):

[0,1,1].union([2,1], [3,1])# => [0, 1, 2, 3]

Preserves order (preserving the position of the first found):

[3,2,1,0].union([5,3], [4,2])# => [3, 2, 1, 0, 5, 4]

With no arguments given, returns a copy ofself.

Related: seeMethods for Combining.

Source
static VALUErb_ary_uniq(VALUE ary){    VALUE hash, uniq;    if (RARRAY_LEN(ary) <= 1) {        hash = 0;        uniq = rb_ary_dup(ary);    }    else if (rb_block_given_p()) {        hash = ary_make_hash_by(ary);        uniq = rb_hash_values(hash);    }    else {        hash = ary_make_hash(ary);        uniq = rb_hash_values(hash);    }    return uniq;}

Returns a new array containing those elements fromself that are not duplicates, the first occurrence always being retained.

With no block given, identifies and omits duplicate elements using methodeql? to compare elements:

a = [0,0,1,1,2,2]a.uniq# => [0, 1, 2]

With a block given, calls the block for each element; identifies and omits “duplicate” elements using methodeql? to compareblock return values; that is, an element is a duplicate if its block return value is the same as that of a previous element:

a = ['a','aa','aaa','b','bb','bbb']a.uniq {|element|element.size }# => ["a", "aa", "aaa"]

Related:Methods for Fetching.

Source
static VALUErb_ary_uniq_bang(VALUE ary){    VALUE hash;    long hash_size;    rb_ary_modify_check(ary);    if (RARRAY_LEN(ary) <= 1)        return Qnil;    if (rb_block_given_p())        hash = ary_make_hash_by(ary);    else        hash = ary_make_hash(ary);    hash_size = RHASH_SIZE(hash);    if (RARRAY_LEN(ary) == hash_size) {        return Qnil;    }    rb_ary_modify_check(ary);    ARY_SET_LEN(ary, 0);    if (ARY_SHARED_P(ary)) {        rb_ary_unshare(ary);        FL_SET_EMBED(ary);    }    ary_resize_capa(ary, hash_size);    rb_hash_foreach(hash, push_value, ary);    return ary;}

Removes duplicate elements fromself, the first occurrence always being retained; returnsself if any elements removed,nil otherwise.

With no block given, identifies and removes elements using methodeql? to compare elements:

a = [0,0,1,1,2,2]a.uniq!# => [0, 1, 2]a.uniq!# => nil

With a block given, calls the block for each element; identifies and omits “duplicate” elements using methodeql? to compareblock return values; that is, an element is a duplicate if its block return value is the same as that of a previous element:

a = ['a','aa','aaa','b','bb','bbb']a.uniq! {|element|element.size }# => ["a", "aa", "aaa"]a.uniq! {|element|element.size }# => nil

Related: seeMethods for Deleting.

Source
VALUErb_ary_unshift_m(int argc, VALUE *argv, VALUE ary){    long len = RARRAY_LEN(ary);    VALUE target_ary;    if (argc == 0) {        rb_ary_modify_check(ary);        return ary;    }    target_ary = ary_ensure_room_for_unshift(ary, argc);    ary_memcpy0(ary, 0, argc, argv, target_ary);    ARY_SET_LEN(ary, len + argc);    return ary;}

Prepends the givenobjects toself:

a = [:foo,'bar',2]a.unshift(:bam,:bat)# => [:bam, :bat, :foo, "bar", 2]

Related:Array#shift; see alsoMethods for Assigning.

Also aliased as:prepend
Source
static VALUErb_ary_values_at(int argc, VALUE *argv, VALUE ary){    long i, olen = RARRAY_LEN(ary);    VALUE result = rb_ary_new_capa(argc);    for (i = 0; i < argc; ++i) {        append_values_at_single(result, ary, olen, argv[i]);    }    RB_GC_GUARD(ary);    return result;}

Returns elements fromself in a new array; does not modifyself.

The objects included in the returned array are the elements ofself selected by the givenspecifiers, each of which must be a numeric index or aRange.

In brief:

a = ['a','b','c','d']# Index specifiers.a.values_at(2,0,2,0)# => ["c", "a", "c", "a"] # May repeat.a.values_at(-4,-3,-2,-1)# => ["a", "b", "c", "d"] # Counts backwards if negative.a.values_at(-50,50)# => [nil, nil]           # Outside of self.# Range specifiers.a.values_at(1..3)# => ["b", "c", "d"] # From range.begin to range.end.a.values_at(1...3)# => ["b", "c"]      # End excluded.a.values_at(3..1)# => []              # No such elements.a.values_at(-3..3)# => ["b", "c", "d"]     # Negative range.begin counts backwards.a.values_at(-50..3)# Raises RangeError.a.values_at(1..-2)# => ["b", "c"]          # Negative range.end counts backwards.a.values_at(1..-50)# => []                  # No such elements.# Mixture of specifiers.a.values_at(2..3,3,0..1,0)# => ["c", "d", "d", "a", "b", "a"]

With nospecifiers given, returns a new empty array:

a = ['a','b','c','d']a.values_at# => []

For each numeric specifierindex, includes an element:

  • For each non-negative numeric specifierindex that is in-range (less thanself.size), includes the element at offsetindex:

    a.values_at(0,2)# => ["a", "c"]a.values_at(0.1,2.9)# => ["a", "c"]
  • For each negative numericindex that is in-range (greater than or equal to- self.size), counts backwards from the end ofself:

    a.values_at(-1,-4)# => ["d", "a"]

The given indexes may be in any order, and may repeat:

a.values_at(2,0,1,0,2)# => ["c", "a", "b", "a", "c"]

For eachindex that is out-of-range, includesnil:

a.values_at(4,-5)# => [nil, nil]

For eachRange specifierrange, includes elements according torange.begin andrange.end:

  • If bothrange.begin andrange.end are non-negative and in-range (less thanself.size), includes elements from indexrange.begin throughrange.end - 1 (ifrange.exclude_end?), or throughrange.end (otherwise):

    a.values_at(1..2)# => ["b", "c"]a.values_at(1...2)# => ["b"]
  • Ifrange.begin is negative and in-range (greater than or equal to- self.size), counts backwards from the end ofself:

    a.values_at(-2..3)# => ["c", "d"]
  • Ifrange.begin is negative and out-of-range, raises an exception:

    a.values_at(-5..3)# Raises RangeError.
  • Ifrange.end is positive and out-of-range, extends the returned array withnil elements:

    a.values_at(1..5)# => ["b", "c", "d", nil, nil]
  • Ifrange.end is negative and in-range, counts backwards from the end ofself:

    a.values_at(1..-2)# => ["b", "c"]
  • Ifrange.end is negative and out-of-range, returns an empty array:

    a.values_at(1..-5)# => []

The given ranges may be in any order and may repeat:

a.values_at(2..3,0..1,2..3)# => ["c", "d", "a", "b", "c", "d"]

The given specifiers may be any mixture of indexes and ranges:

a.values_at(3,1..2,0,2..3)# => ["d", "b", "c", "a", "c", "d"]

Related: seeMethods for Fetching.

Source
static VALUErb_ary_zip(int argc, VALUE *argv, VALUE ary){    int i, j;    long len = RARRAY_LEN(ary);    VALUE result = Qnil;    for (i=0; i<argc; i++) {        argv[i] = take_items(argv[i], len);    }    if (rb_block_given_p()) {        int arity = rb_block_arity();        if (arity > 1) {            VALUE work, *tmp;            tmp = ALLOCV_N(VALUE, work, argc+1);            for (i=0; i<RARRAY_LEN(ary); i++) {                tmp[0] = RARRAY_AREF(ary, i);                for (j=0; j<argc; j++) {                    tmp[j+1] = rb_ary_elt(argv[j], i);                }                rb_yield_values2(argc+1, tmp);            }            if (work) ALLOCV_END(work);        }        else {            for (i=0; i<RARRAY_LEN(ary); i++) {                VALUE tmp = rb_ary_new2(argc+1);                rb_ary_push(tmp, RARRAY_AREF(ary, i));                for (j=0; j<argc; j++) {                    rb_ary_push(tmp, rb_ary_elt(argv[j], i));                }                rb_yield(tmp);            }        }    }    else {        result = rb_ary_new_capa(len);        for (i=0; i<len; i++) {            VALUE tmp = rb_ary_new_capa(argc+1);            rb_ary_push(tmp, RARRAY_AREF(ary, i));            for (j=0; j<argc; j++) {                rb_ary_push(tmp, rb_ary_elt(argv[j], i));            }            rb_ary_push(result, tmp);        }    }    return result;}

With no block given, combinesself with the collection ofother_arrays; returns a new array of sub-arrays:

[0,1].zip(['zero','one'], [:zero,:one])# => [[0, "zero", :zero], [1, "one", :one]]

Returned:

  • The outer array is of sizeself.size.

  • Each sub-array is of sizeother_arrays.size + 1.

  • Thenth sub-array contains (in order):

    • Thenth element ofself.

    • Thenth element of each of the other arrays, as available.

Example:

a = [0,1]zipped =a.zip(['zero','one'], [:zero,:one])# => [[0, "zero", :zero], [1, "one", :one]]zipped.size# => 2 # Same size as a.zipped.first.size# => 3 # Size of other arrays plus 1.

When the other arrays are all the same size asself, the returned sub-arrays are a rearrangement containing exactly elements of all the arrays (includingself), with no omissions or additions:

a = [:a0,:a1,:a2,:a3]b = [:b0,:b1,:b2,:b3]c = [:c0,:c1,:c2,:c3]d =a.zip(b,c)ppd# =>[[:a0,:b0,:c0], [:a1,:b1,:c1], [:a2,:b2,:c2], [:a3,:b3,:c3]]

When one of the other arrays is smaller thanself, pads the corresponding sub-array withnil elements:

a = [:a0,:a1,:a2,:a3]b = [:b0,:b1,:b2]c = [:c0,:c1]d =a.zip(b,c)ppd# =>[[:a0,:b0,:c0], [:a1,:b1,:c1], [:a2,:b2,nil], [:a3,nil,nil]]

When one of the other arrays is larger thanself,ignores its trailing elements:

a = [:a0,:a1,:a2,:a3]b = [:b0,:b1,:b2,:b3,:b4]c = [:c0,:c1,:c2,:c3,:c4,:c5]d =a.zip(b,c)ppd# =>[[:a0,:b0,:c0], [:a1,:b1,:c1], [:a2,:b2,:c2], [:a3,:b3,:c3]]

With a block given, calls the block with each of the other arrays; returnsnil:

d = []a = [:a0,:a1,:a2,:a3]b = [:b0,:b1,:b2,:b3]c = [:c0,:c1,:c2,:c3]a.zip(b,c) {|sub_array|d.push(sub_array.reverse) }# => nilppd# =>[[:c0,:b0,:a0], [:c1,:b1,:a1], [:c2,:b2,:a2], [:c3,:b3,:a3]]

For anobject inother_arrays that is not actually an array, forms the “other array” asobject.to_ary, if defined, or asobject.each.to_a otherwise.

Related: seeMethods for Converting.