Arrays are ordered, integer-indexed collections of any object.
Array indexing starts at 0, as in C or Java. A negative index is assumed to be relative to the end of the array—that is, an index of -1 indicates the last element of the array, -2 is the next to last element in the array, and so on.
A new array can be created by using the literal constructor []
. Arrays can contain different types of objects. For example, the array below contains an Integer
, a String and a Float:
ary = [1, "two", 3.0] #=> [1, "two", 3.0]
An array can also be created by explicitly calling Array.new
with zero, one (the initial size of the Array) or two arguments (the initial size and a default object).
ary = Array.new #=> [] Array.new(3) #=> [nil, nil, nil] Array.new(3, true) #=> [true, true, true]
Note that the second argument populates the array with references to the same object. Therefore, it is only recommended in cases when you need to instantiate arrays with natively immutable objects such as Symbols, numbers, true or false.
To create an array with separate objects a block can be passed instead. This method is safe to use with mutable objects such as hashes, strings or other arrays:
Array.new(4) { Hash.new } #=> [{}, {}, {}, {}] Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]
This is also a quick way to build up multi-dimensional arrays:
empty_table = Array.new(3) { Array.new(3) } #=> [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
An array can also be created by using the Array() method, provided by Kernel
, which tries to call to_ary
, then to_a
on its argument.
Array({:a => "a", :b => "b"}) #=> [[:a, "a"], [:b, "b"]]
In addition to the methods it mixes in through the Enumerable
module, the Array class has proprietary methods for accessing, searching and otherwise manipulating arrays.
Some of the more common ones are illustrated below.
Elements in an array can be retrieved using the Array#[]
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] #=> 3 arr[100] #=> nil arr[-3] #=> 4 arr[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 the at
method
arr.at(0) #=> 1
The slice
method works in an identical manner to Array#[]
.
To raise an error for indices outside of the array bounds or else to provide a default value when that happens, you can use fetch
.
arr = ['a', 'b', 'c', 'd', 'e', 'f'] arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6 arr.fetch(100, "oops") #=> "oops"
The special methods first
and last
will return the first and last elements of an array, respectively.
arr.first #=> 1 arr.last #=> 6
To return the first n
elements of an array, use take
arr.take(3) #=> [1, 2, 3]
drop
does the opposite of take
, by returning the elements after n
elements have been dropped:
arr.drop(3) #=> [4, 5, 6]
Arrays keep track of their own length at all times. To query an array about the number of elements it contains, use length
, count
or size
.
browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE'] browsers.length #=> 5 browsers.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
Items can be added to the end of an array by using either push
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]
With insert
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 the insert
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]
The method pop
removes the last element in an array and returns it:
arr = [1, 2, 3, 4, 5, 6] arr.pop #=> 6 arr #=> [1, 2, 3, 4, 5]
To retrieve and at the same time remove the first item, use shift
:
arr.shift #=> 1 arr #=> [2, 3, 4, 5]
To delete an element at a particular index:
arr.delete_at(2) #=> 4 arr #=> [2, 3, 5]
To delete a particular element anywhere in an array, use delete
:
arr = [1, 2, 2, 3] arr.delete(2) #=> 2 arr #=> [1,3]
A useful method if you need to remove nil
values from an array is compact
:
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-destructive uniq
, and destructive method uniq!
arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556] arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]
Like all classes that include the Enumerable
module, Array has an each method, which defines what elements should be iterated over and how. In case of Array’s each
, all elements in the Array instance 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| print a -= 10, " " } # prints: -9 -8 -7 -6 -5 #=> [1, 2, 3, 4, 5]
Another sometimes useful iterator is reverse_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} " } p str #=> "sixth fifth fourth third second first "
The map
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]
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.
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]
select!
and reject!
are the corresponding destructive methods to select
and reject
Similar to select
vs. reject
, delete_if
and keep_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]
Returns arg
as an Array.
First tries to call to_ary
on arg
, then to_a
.
Array(1..5) #=> [1, 2, 3, 4, 5]
Assumes that self
is an array of arrays and transposes the rows and columns.
a = [[1,2], [3,4], [5,6]] a.transpose #=> [[1, 3, 5], [2, 4, 6]]
If the length of the subarrays don’t match, an IndexError
is raised.
Searches through the array whose elements are also arrays.
Compares obj
with the second element of each contained array using obj.==
.
Returns the first contained array that matches obj
.
See also Array#assoc
.
a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] a.rassoc("two") #=> [2, "two"] a.rassoc("four") #=> nil
By using binary search, finds a value from this array which meets the given condition in O(log n) where n is the size of the array.
You can use this method in two use cases: a find-minimum mode and a find-any mode. In either case, the elements of the array must be monotone (or sorted) with respect to the block.
In find-minimum mode (this is a good choice for typical use case), the block must return true or false, and there must be an index i (0 <= i <= ary.size) so that:
the block returns false for any element whose index is less than i, and
the block returns true for any element whose index is greater than or equal to i.
This method returns the i-th element. If i is equal to ary.size, it returns nil.
ary = [0, 4, 7, 10, 12] ary.bsearch {|x| x >= 4 } #=> 4 ary.bsearch {|x| x >= 6 } #=> 7 ary.bsearch {|x| x >= -1 } #=> 0 ary.bsearch {|x| x >= 100 } #=> nil
In find-any mode (this behaves like libc’s bsearch(3)), the block must return a number, and there must be two indices i and j (0 <= i <= j <= ary.size) so that:
the block returns a positive number for ary if 0 <= k < i,
the block returns zero for ary if i <= k < j, and
the block returns a negative number for ary if j <= k < ary.size.
Under this condition, this method returns any element whose index is within i…j. If i is equal to j (i.e., there is no element that satisfies the block), this method returns nil.
ary = [0, 4, 7, 10, 12] # try to find v such that 4 <= v < 8 ary.bsearch {|x| 1 - x / 4 } #=> 4 or 7 # try to find v such that 8 <= v < 10 ary.bsearch {|x| 4 - x / 2 } #=> nil
You must not mix the two modes at a time; the block must always return either true/false, or always return a number. It is undefined which value is actually picked up at each iteration.
Returns Ruby object wrapping OLE variant whose variant type is VT_ARRAY. The first argument should be Array object which specifies dimensions and each size of dimensions of OLE array. The second argument specifies variant type of the element of OLE array.
The following create 2 dimensions OLE array. The first dimensions size is 3, and the second is 4.
ole_ary = WIN32OLE_VARIANT.array([3,4], VT_I4) ruby_ary = ole_ary.value # => [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Returns self
.
By using binary search, finds an index of a value from this array which meets the given condition in O(log n) where n is the size of the array.
It supports two modes, depending on the nature of the block and they are exactly the same as in the case of bsearch
method with the only difference being that this method returns the index of the element instead of the element itself. For more details consult the documentation for bsearch
.
Returns a new array populated with the given objects.
Array.[]( 1, 'a', /^A/ ) # => [1, "a", /^A/] Array[ 1, 'a', /^A/ ] # => [1, "a", /^A/] [ 1, 'a', /^A/ ] # => [1, "a", /^A/]
Returns a new array.
In the first form, if no arguments are sent, the new array will be empty. When a size
and an optional default
are sent, an array is created with size
copies of default
. Take notice that all elements will reference the same object default
.
The second form creates a copy of the array passed as a parameter (the array is generated by calling to_ary
on the parameter).
first_array = ["Matz", "Guido"] second_array = Array.new(first_array) #=> ["Matz", "Guido"] first_array.equal? second_array #=> false
In the last form, an array of the given size is created. Each element in this array is created by passing the element’s index to the given block and storing the return value.
Array.new(3){ |index| index ** 2 } # => [0, 1, 4]
When sending the second parameter, the same object will be used as the value for all the array elements:
a = Array.new(2, Hash.new) # => [{}, {}] a[0]['cat'] = 'feline' a # => [{"cat"=>"feline"}, {"cat"=>"feline"}] a[1]['cat'] = 'Felix' a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}]
Since all the Array elements store the same hash, changes to one of them will affect them all.
If multiple copies are what you want, you should use the block version which uses the result of that block each time an element of the array needs to be initialized:
a = Array.new(2) { Hash.new } a[0]['cat'] = 'feline' a # => [{"cat"=>"feline"}, {}]
Creates a string representation of self
.
[ "a", "b", "c" ].to_s #=> "[\"a\", \"b\", \"c\"]"
Return true
if this array is frozen (or temporarily frozen while being sorted). See also Object#frozen?
Equality — Two arrays are equal if they contain the same number of elements and if each element is equal to (according to Object#==
) the corresponding element in other_ary
.
[ "a", "c" ] == [ "a", "c", 7 ] #=> false [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
Returns true
if self
and other
are the same object, or are both arrays with the same content (according to Object#eql?
).
Compute a hash-code for this array.
Two arrays with the same content will have the same hash code (and will compare using eql?
).
See also Object#hash
.
Element Reference — Returns the element at index
, or returns a subarray starting at the start
index and continuing for length
elements, or returns a subarray specified by range
of indices.
Negative indices count backward from the end of the array (-1 is the last element). For start
and range
cases the starting index is just before an element. Additionally, an empty array is returned when the starting index for an element range is at the end of the array.
Returns nil
if the index (or starting index) are out of range.
a = [ "a", "b", "c", "d", "e" ] a[2] + a[0] + a[1] #=> "cab" a[6] #=> nil a[1, 2] #=> [ "b", "c" ] a[1..3] #=> [ "b", "c", "d" ] a[4..7] #=> [ "e" ] a[6..10] #=> nil a[-3, 3] #=> [ "c", "d", "e" ] # special cases a[5] #=> nil a[6, 1] #=> nil a[5, 1] #=> [] a[5..10] #=> []
Element Assignment — Sets the element at index
, or replaces a subarray from the start
index for length
elements, or replaces a subarray specified by the range
of indices.
If indices are greater than the current capacity of the array, the array grows automatically. Elements are inserted into the array at start
if length
is zero.
Negative indices will count backward from the end of the array. For start
and range
cases the starting index is just before an element.
An IndexError
is raised if a negative index points past the beginning of the array.
See also Array#push
, and Array#unshift
.
a = Array.new a[4] = "4"; #=> [nil, nil, nil, nil, "4"] a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"] a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"] a[0, 2] = "?" #=> ["?", 2, nil, "4"] a[0..2] = "A" #=> ["A", "4"] a[-1] = "Z" #=> ["A", "Z"] a[1..-1] = nil #=> ["A", nil] a[1..-1] = [] #=> ["A"] a[0, 0] = [ 1, 2 ] #=> [1, 2, "A"] a[3, 0] = "B" #=> [1, 2, "A", "B"]
Returns the element at index
. A negative index counts from the end of self
. Returns nil
if the index is out of range. See also Array#[]
.
a = [ "a", "b", "c", "d", "e" ] a.at(0) #=> "a" a.at(-1) #=> "e"
Tries to return the element at position index
, but throws an IndexError
exception if the referenced index
lies outside of the array bounds. This error can be prevented by supplying a second argument, which will act as a default
value.
Alternatively, if a block is given it will only be executed when an invalid index
is referenced. Negative values of index
count from the end of the array.
a = [ 11, 22, 33, 44 ] a.fetch(1) #=> 22 a.fetch(-1) #=> 44 a.fetch(4, 'cat') #=> "cat" a.fetch(100) { |i| puts "#{i} is out of bounds" } #=> "100 is out of bounds"
Returns the first element, or the first n
elements, of the array. If the array is empty, the first form returns nil
, and the second form returns an empty array. See also Array#last
for the opposite effect.
a = [ "q", "r", "s", "t" ] a.first #=> "q" a.first(2) #=> ["q", "r"]
Returns the last element(s) of self
. If the array is empty, the first form returns nil
.
See also Array#first
for the opposite effect.
a = [ "w", "x", "y", "z" ] a.last #=> "z" a.last(2) #=> ["y", "z"]
Appends the elements of other_ary
to self
.
[ "a", "b" ].concat( ["c", "d"] ) #=> [ "a", "b", "c", "d" ] a = [ 1, 2, 3 ] a.concat( [ 4, 5 ] ) a #=> [ 1, 2, 3, 4, 5 ]
See also Array#+
.
Append—Pushes the given object on to the end of this array. This expression returns the array itself, so several appends may be chained together.
[ 1, 2 ] << "c" << "d" << [ 3, 4 ] #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
Append — Pushes the given object(s) on to the end of this array. This expression returns the array itself, so several appends may be chained together. See also Array#pop
for the opposite effect.
a = [ "a", "b", "c" ] a.push("d", "e", "f") #=> ["a", "b", "c", "d", "e", "f"] [1, 2, 3,].push(4).push(5) #=> [1, 2, 3, 4, 5]