Class: Array
Overview
An Array is an ordered, integer-indexed collection of objects, called elements. Any object may be an Array element.
Array Indexes
Array indexing starts at 0, as in C or Java.
A positive index is an offset from the first element:
-
Index 0 indicates the first element.
-
Index 1 indicates the second element.
-
…
A negative index is an offset, backwards, from the end of the array:
-
Index -1 indicates the last element.
-
Index -2 indicates the next-to-last element.
-
…
A non-negative index is in range if it is smaller than the size of the array. For a 3-element array:
-
Indexes 0 through 2 are in range.
-
Index 3 is out of range.
A negative index is in range if its absolute value is not larger than the size of the array. For a 3-element array:
-
Indexes -1 through -3 are in range.
-
Index -4 is out of range.
Creating Arrays
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”, :b => “b”) #=> [[:a, “a”], [:b, “b”]]
Example Usage
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.
Accessing Elements
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]
Obtaining Information about an Array
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
Adding Items to Arrays
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]
Removing Items from an Array
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]
Iterating over Arrays
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]
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! 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]
Class Method Summary collapse
-
.[](*args) ⇒ Object
Returns a new array populated with the given objects.
-
.try_convert(object) ⇒ Object?
If
object
is an Array object, returnsobject
.
Instance Method Summary collapse
-
#&(other_array) ⇒ Object
Returns a new Array containing each element found in both
array
and Arrayother_array
; duplicates are omitted; items are compared usingeql?
: [0, 1, 2, 3] & [1, 2] # => [1, 2] [0, 1, 0, 1] & [0, 1] # => [0, 1]. -
#*(times) ⇒ Object
When non-negative argument Integer
n
is given, returns a new Array built by concatenating then
copies ofself
: a = [‘x’, ‘y’] a * 3 # => [“x”, “y”, “x”, “y”, “x”, “y”]. -
#+(other_array) ⇒ Object
Returns a new Array containing all elements of
array
followed by all elements ofother_array
: a = [0, 1] + [2, 3] a # => [0, 1, 2, 3]. -
#-(other_array) ⇒ Object
Returns a new Array containing only those elements from
array
that are not found in Arrayother_array
; items are compared usingeql?
; the order fromarray
is preserved: [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3] [0, 1, 2, 3] - [3, 0] # => [1, 2] [0, 1, 2] - [4] # => [0, 1, 2]. -
#<<(object) ⇒ self
Appends
object
toself
; returnsself
: a = [:foo, ‘bar’, 2] a << :baz # => [:foo, “bar”, 2, :baz]. -
#<=>(other_array) ⇒ -1, ...
Returns -1, 0, or 1 as
self
is less than, equal to, or greater thanother_array
. -
#==(other_array) ⇒ Boolean
Returns
true
if botharray.size == other_array.size
and for each indexi
inarray
,array[i] == other_array[i]
: a0 = [:foo, ‘bar’, 2] a1 = [:foo, ‘bar’, 2.0] a1 == a0 # => true [] == [] # => true. -
#[](*args) ⇒ Object
Returns elements from
self
; does not modifyself
. -
#[]=(*args) ⇒ Object
Assigns elements in
self
; returns the givenobject
. -
#all?(*args) ⇒ Object
Returns
true
if all elements ofself
meet a given criterion. -
#any?(*args) ⇒ Object
Returns
true
if any element ofself
meets a given criterion. -
#assoc(obj) ⇒ nil
Returns the first element in
self
that is an Array whose first element==
obj
: a = [0, [2, 4], [4, 5, 6], [4, 5]] a.assoc(4) # => [4, 5, 6]. -
#at(index) ⇒ Object
Returns the element at Integer offset
index
; does not modifyself
. -
#bsearch ⇒ Object
Returns an element from
self
selected by a binary search. -
#bsearch_index ⇒ Object
Searches
self
as described at method #bsearch, but returns the index of the found element instead of the element itself. -
#clear ⇒ self
Removes all elements from
self
: a = [:foo, ‘bar’, 2] a.clear # => []. -
#collect ⇒ Object
Calls the block, if given, with each element of
self
; 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]. -
#collect! ⇒ Object
Calls the block, if given, with each element; replaces the element with the block’s return value: a = [:foo, ‘bar’, 2] a.map! { |element| element.class } # => [Symbol, String, Integer].
-
#combination(num) ⇒ Object
Calls the block, if given, with combinations of elements of
self
; returnsself
. -
#compact ⇒ Object
Returns a new Array containing all non-
nil
elements fromself
: a = [nil, 0, nil, 1, nil, 2, nil] a.compact # => [0, 1, 2]. -
#compact! ⇒ self?
Removes all
nil
elements fromself
. -
#concat(*other_arrays) ⇒ self
Adds to
array
all elements from each Array inother_arrays
; returnsself
: a = [0, 1] a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5]. -
#count(*args) ⇒ Object
Returns a count of specified elements.
-
#cycle(*args) ⇒ Object
When called with positive Integer argument
count
and a block, calls the block with each element, then does so again, until it has done socount
times; returnsnil
: output = [] [0, 1].cycle(2) {|element| output.push(element) } # => nil output # => [0, 1, 0, 1]. - #deconstruct ⇒ Object
-
#delete(item) ⇒ Object
Removes zero or more elements from
self
; returnsself
. -
#delete_at(index) ⇒ nil
Deletes an element from
self
, per the given Integerindex
. -
#delete_if ⇒ Object
Removes each element in
self
for which the block returns a truthy value; returnsself
: a = [:foo, ‘bar’, 2, ‘bat’] a.delete_if {|element| element.to_s.start_with?(‘b’) } # => [:foo, 2]. -
#difference(*other_arrays) ⇒ Object
Returns a new Array containing only those elements from
self
that are not found in any of the Arraysother_arrays
; items are compared usingeql?
; order fromself
is preserved: [0, 1, 1, 2, 1, 1, 3, 1, 1].difference() # => [0, 2, 3] [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2] [0, 1, 2].difference() # => [0, 1, 2]. -
#dig(index, *identifiers) ⇒ Object
Finds and returns the object in nested objects that is specified by
index
andidentifiers
. -
#drop(n) ⇒ Object
Returns a new Array containing all but the first
n
element ofself
, wheren
is a non-negative Integer; does not modifyself
. -
#drop_while ⇒ Object
Returns a new Array containing zero or more trailing elements of
self
; does not modifyself
. -
#each ⇒ Object
Iterates over array elements.
-
#each_index ⇒ Object
Iterates over array indexes.
-
#empty? ⇒ Boolean
Returns
true
if the count of elements inself
is zero,false
otherwise. -
#eql?(other_array) ⇒ Boolean
Returns
true
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. -
#fetch(*args) ⇒ Object
Returns the element at offset
index
. -
#fill(*args) ⇒ Object
Replaces specified elements in
self
with specified objects; returnsself
. -
#filter ⇒ Object
Calls the block, if given, with each element of
self
; returns a new Array containing those elements ofself
for which the block returns a truthy value: a = [:foo, ‘bar’, 2, :bam] a1 = a.select {|element| element.to_s.start_with?(‘b’) } a1 # => [“bar”, :bam]. -
#filter! ⇒ Object
Calls the block, if given with each element of
self
; removes fromself
those elements for which the block returnsfalse
ornil
. -
#find_index(*args) ⇒ Object
Returns the index of a specified element.
-
#first(*args) ⇒ Object
Returns elements from
self
; does not modifyself
. -
#flatten(*args) ⇒ Object
Returns a new Array that is a recursive flattening of
self
: - Each non-Array element is unchanged. -
#flatten!(*args) ⇒ Object
Replaces each nested Array in
self
with the elements from that Array; returnsself
if any changes,nil
otherwise. -
#hash ⇒ Integer
Returns the integer hash value for
self
. -
#include?(obj) ⇒ Boolean
Returns
true
if for some indexi
inself
,obj == self[i]
; otherwisefalse
: [0, 1, 2].include?(2) # => true [0, 1, 2].include?(3) # => false. -
#index(*args) ⇒ Object
Returns the index of a specified element.
-
#initialize(*args) ⇒ Object
constructor
Returns a new Array.
-
#replace(other_array) ⇒ self
Replaces the content of
self
with the content ofother_array
; returnsself
: a = [:foo, ‘bar’, 2] a.replace([‘foo’, :bar, 3]) # => [“foo”, :bar, 3]. -
#insert(index, *objects) ⇒ self
Inserts given
objects
before or after the element at Integer indexoffset
; returnsself
. -
#inspect ⇒ Object
(also: #to_s)
Returns the new String formed by calling method
#inspect
on each array element: a = [:foo, ‘bar’, 2] a.inspect # => “[:foo, "bar", 2]”. -
#intersection(*other_arrays) ⇒ Object
Returns a new Array containing each element found both in
self
and in all of the given Arraysother_arrays
; duplicates are omitted; items are compared usingeql?
: [0, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1] [0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]. -
#join(*args) ⇒ Object
Returns the new String formed by joining the array elements after conversion.
-
#keep_if ⇒ Object
Retains those elements for which the block returns a truthy value; deletes all other elements; returns
self
: a = [:foo, ‘bar’, 2, :bam] a.keep_if {|element| element.to_s.start_with?(‘b’) } # => [“bar”, :bam]. -
#last(*args) ⇒ Object
Returns elements from
self
;self
is not modified. -
#length ⇒ Integer
(also: #size)
Returns the count of elements in
self
. -
#map ⇒ Object
Calls the block, if given, with each element of
self
; 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]. -
#map! ⇒ Object
Calls the block, if given, with each element; replaces the element with the block’s return value: a = [:foo, ‘bar’, 2] a.map! { |element| element.class } # => [Symbol, String, Integer].
-
#max(*args) ⇒ Object
Returns one of the following: - The maximum-valued element from
self
. -
#min(*args) ⇒ Object
Returns one of the following: - The minimum-valued element from
self
. -
#minmax ⇒ Object
Returns a new 2-element Array containing the minimum and maximum values from
self
, either per method<=>
or per a given block:. -
#none?(*args) ⇒ Object
Returns
true
if no element ofself
meet a given criterion. -
#one?(*args) ⇒ Object
Returns
true
if exactly one element ofself
meets a given criterion. -
#permutation(*args) ⇒ Object
When invoked with a block, yield all permutations of elements of
self
; returnsself
. -
#pop(*args) ⇒ Object
Removes and returns trailing elements.
-
#product(*args) ⇒ Object
Computes and returns or yields all combinations of elements from all the Arrays, including both
self
andother_arrays
. -
#push(*objects) ⇒ self
(also: #append)
Appends trailing elements.
-
#rassoc(obj) ⇒ nil
Returns the first element in
self
that is an Array whose second element==
obj
: a = [0, [2, 4], [4, 5, 6], [4, 5]] a.rassoc(4) # => [2, 4]. -
#reject ⇒ Object
Returns a new Array whose elements are all those from
self
for which the block returnsfalse
ornil
: a = [:foo, ‘bar’, 2, ‘bat’] a1 = a.reject {|element| element.to_s.start_with?(‘b’) } a1 # => [:foo, 2]. -
#reject! ⇒ Object
Removes each element for which the block returns a truthy value.
-
#repeated_combination(num) ⇒ Object
Calls the block with each repeated combination of length
n
of the elements ofself
; each combination is an Array; returnsself
. -
#repeated_permutation(num) ⇒ Object
Calls the block with each repeated permutation of length
n
of the elements ofself
; each permutation is an Array; returnsself
. -
#replace(other_array) ⇒ self
Replaces the content of
self
with the content ofother_array
; returnsself
: a = [:foo, ‘bar’, 2] a.replace([‘foo’, :bar, 3]) # => [“foo”, :bar, 3]. -
#reverse ⇒ Object
Returns a new Array with the elements of
self
in reverse order. -
#reverse! ⇒ self
Reverses
self
in place: a = [‘foo’, ‘bar’, ‘two’] a.reverse! # => [“two”, “bar”, “foo”]. -
#reverse_each ⇒ Object
Iterates backwards over array elements.
-
#rindex(*args) ⇒ Object
Returns the index of the last element for which
object == element
. -
#rotate(*args) ⇒ Object
Returns a new Array formed from
self
with elements rotated from one end to the other. -
#rotate!(*args) ⇒ Object
Rotates
self
in place by moving elements from one end to the other; returnsself
. -
#select ⇒ Object
Calls the block, if given, with each element of
self
; returns a new Array containing those elements ofself
for which the block returns a truthy value: a = [:foo, ‘bar’, 2, :bam] a1 = a.select {|element| element.to_s.start_with?(‘b’) } a1 # => [“bar”, :bam]. -
#select! ⇒ Object
Calls the block, if given with each element of
self
; removes fromself
those elements for which the block returnsfalse
ornil
. -
#shift(*args) ⇒ Object
Removes and returns leading elements.
-
#slice(*args) ⇒ Object
Returns elements from
self
; does not modifyself
. -
#slice!(*args) ⇒ Object
Removes and returns elements from
self
. -
#sort ⇒ Object
Returns a new Array whose elements are those from
self
, sorted. -
#sort! ⇒ Object
Returns
self
with its elements sorted in place. -
#sort_by! ⇒ Object
Sorts the elements of
self
in place, using an ordering determined by the block; returns self. -
#sum(*args) ⇒ Object
When no block is given, returns the object equivalent to: sum = init array.each {|element| sum = element } sum For example,
[e1, e2, e3].sum
returns </tt>init e1 + e2 + e3</tt>. -
#take(n) ⇒ Object
Returns a new Array containing the first
n
element ofself
, wheren
is a non-negative Integer; does not modifyself
. -
#take_while ⇒ Object
Returns a new Array containing zero or more leading elements of
self
; does not modifyself
. -
#to_a ⇒ self
When
self
is an instance of Array, returnsself
: a = [:foo, ‘bar’, 2] a.to_a # => [:foo, “bar”, 2]. -
#to_ary ⇒ self
Returns
self
. -
#to_h ⇒ Object
Returns a new Hash formed from
self
. -
#transpose ⇒ Object
Transposes the rows and columns in an Array of Arrays; the nested Arrays must all be the same size: a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]] a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]].
-
#union(*other_arrays) ⇒ Object
Returns a new Array that is the union of
self
and all given Arraysother_arrays
; duplicates are removed; order is preserved; items are compared usingeql?
: [0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3] [0, 1, 2, 3].union([3, 2], [1, 0]) # => [0, 1, 2, 3]. -
#uniq ⇒ Object
Returns a new Array containing those elements from
self
that are not duplicates, the first occurrence always being retained. -
#uniq! ⇒ Object
Removes duplicate elements from
self
, the first occurrence always being retained; returnsself
if any elements removed,nil
otherwise. -
#unshift(*objects) ⇒ self
(also: #prepend)
Prepends the given
objects
toself
: a = [:foo, ‘bar’, 2] a.unshift(:bam, :bat) # => [:bam, :bat, :foo, “bar”, 2]. -
#values_at(*indexes) ⇒ Object
Returns a new Array whose elements are the elements of
self
at the given Integerindexes
. -
#zip(*args) ⇒ Object
When no block given, returns a new Array
new_array
of sizeself.size
whose elements are Arrays. -
#|(other_array) ⇒ Object
Returns the union of
array
and Arrayother_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].
Methods included from Enumerable
#chain, #chunk, #chunk_while, #collect_concat, #detect, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #filter_map, #find, #find_all, #flat_map, #grep, #grep_v, #group_by, #inject, #lazy, #max_by, #member?, #min_by, #minmax_by, #partition, #reduce, #slice_after, #slice_before, #slice_when, #sort_by, #tally
Constructor Details
#new ⇒ Object #new(array) ⇒ Object #new(size) ⇒ Object #new(size, default_value) ⇒ Object #new(size) {|index| ... } ⇒ Object
Returns a new Array.
With no block and no arguments, returns a new empty Array object.
With no block and a single Array argument array
, returns a new Array formed from array
:
a = Array.new([:foo, 'bar', 2])
a.class # => Array
a # => [:foo, "bar", 2]
With no block and a single Integer argument size
, returns a new Array of the given size whose elements are all nil
:
a = Array.new(3)
a # => [nil, nil, nil]
With no block and arguments size
and default_value
, returns an Array of the given size; each element is that same default_value
:
a = Array.new(3, 'x')
a # => ['x', 'x', 'x']
With a block and argument size
, returns an Array of the given size; the block is called with each successive integer index
; the element for that index
is the return value from the block:
a = Array.new(3) {|index| "Element #{index}" }
a # => ["Element 0", "Element 1", "Element 2"]
Raises ArgumentError if size
is negative.
With a block and no argument, or a single argument 0
, ignores the block and returns a new empty Array.
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 |
# File 'array.c', line 1063
static VALUE
rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
{
long len;
VALUE size, val;
rb_ary_modify(ary);
if (argc == 0) {
if (ARY_OWNS_HEAP_P(ary) && ARY_HEAP_PTR(ary) != NULL) {
ary_heap_free(ary);
}
rb_ary_unshare_safe(ary);
FL_SET_EMBED(ary);
ARY_SET_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;
}
|
Class Method Details
.[](*args) ⇒ Object
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 |
# File 'array.c', line 1128
static VALUE
rb_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;
}
|
.try_convert(object) ⇒ Object?
If object
is an Array object, returns object
.
Otherwise if object
responds to :to_ary
, calls object.to_ary
and returns the result.
Returns nil
if object
does not respond to :to_ary
Raises an exception unless object.to_ary
returns an Array object.
1013 1014 1015 1016 1017 |
# File 'array.c', line 1013
static VALUE
rb_ary_s_try_convert(VALUE dummy, VALUE ary)
{
return rb_check_array_type(ary);
}
|
Instance Method Details
#&(other_array) ⇒ Object
Returns a new Array containing each element found in both array
and Array other_array
; duplicates are omitted; items are compared using eql?
:
[0, 1, 2, 3] & [1, 2] # => [1, 2]
[0, 1, 0, 1] & [0, 1] # => [0, 1]
Preserves order from array
:
[0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2]
Related: Array#intersection.
5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 |
# File 'array.c', line 5383
static VALUE
rb_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);
}
}
ary_recycle_hash(hash);
return ary3;
}
|
#*(n) ⇒ Object #*(string_separator) ⇒ Object
When non-negative argument Integer n
is given, returns a new Array built by concatenating the n
copies of self
:
a = ['x', 'y']
a * 3 # => ["x", "y", "x", "y", "x", "y"]
When String argument string_separator
is given, equivalent to array.join(string_separator)
:
[0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}"
4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 |
# File 'array.c', line 4877
static VALUE
rb_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_TRANSIENT(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_TRANSIENT(ary2));
t *= 2;
}
if (t < len) {
ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR_TRANSIENT(ary2));
}
}
out:
return ary2;
}
|
#+(other_array) ⇒ Object
Returns a new Array containing all elements of array
followed by all elements of other_array
:
a = [0, 1] + [2, 3]
a # => [0, 1, 2, 3]
Related: #concat.
4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 |
# File 'array.c', line 4798
VALUE
rb_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_TRANSIENT(x));
ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR_TRANSIENT(y));
ARY_SET_LEN(z, len);
return z;
}
|
#-(other_array) ⇒ Object
Returns a new Array containing only those elements from array
that are not found in Array other_array
; items are compared using eql?
; the order from array
is preserved:
[0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3]
[0, 1, 2, 3] - [3, 0] # => [1, 2]
[0, 1, 2] - [4] # => [0, 1, 2]
Related: Array#difference.
5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 |
# File 'array.c', line 5286
static VALUE
rb_ary_diff(VALUE ary1, VALUE ary2)
{
VALUE ary3;
VALUE hash;
long i;
ary2 = to_ary(ary2);
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));
}
ary_recycle_hash(hash);
return ary3;
}
|
#<<(object) ⇒ self
Appends object
to self
; returns self
:
a = [:foo, 'bar', 2]
a << :baz # => [:foo, "bar", 2, :baz]
Appends object
as one element, even if it is another Array:
a = [:foo, 'bar', 2]
a1 = a << [3, 4]
a1 # => [:foo, "bar", 2, [3, 4]]
1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 |
# File 'array.c', line 1300
VALUE
rb_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_TRANSIENT(ary, ptr, {
RB_OBJ_WRITE(target_ary, &ptr[idx], item);
});
ARY_SET_LEN(ary, idx + 1);
ary_verify(ary);
return ary;
}
|
#<=>(other_array) ⇒ -1, ...
Returns -1, 0, or 1 as self
is less than, equal to, or greater than other_array
. For each index i
in self
, evaluates result = self[i] <=> other_array[i]
.
Returns -1 if any result is -1:
[0, 1, 2] <=> [0, 1, 3] # => -1
Returns 1 if any result is 1:
[0, 1, 2] <=> [0, 1, 1] # => 1
When all results are zero:
-
Returns -1 if
array
is smaller thanother_array
:[0, 1, 2] <=> [0, 1, 2, 3] # => -1
-
Returns 1 if
array
is larger thanother_array
:[0, 1, 2] <=> [0, 1] # => 1
-
Returns 0 if
array
andother_array
are the same size:[0, 1, 2] <=> [0, 1, 2] # => 0
5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 |
# File 'array.c', line 5195
VALUE
rb_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 (v != Qundef) return v;
len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
if (len == 0) return INT2FIX(0);
if (len > 0) return INT2FIX(1);
return INT2FIX(-1);
}
|
#==(other_array) ⇒ Boolean
Returns true
if both array.size == other_array.size
and for each index i
in array
, array[i] == other_array[i]
:
a0 = [:foo, 'bar', 2]
a1 = [:foo, 'bar', 2.0]
a1 == a0 # => true
[] == [] # => true
Otherwise, returns false
.
This method is different from method Array#eql?, which compares elements using Object#eql?
.
5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 |
# File 'array.c', line 5031
static VALUE
rb_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_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
}
|
#[](index) ⇒ Object? #[](start, length) ⇒ Object? #[](range) ⇒ Object? #[](aseq) ⇒ Object? #slice(index) ⇒ Object? #slice(start, length) ⇒ Object? #slice(range) ⇒ Object? #slice(aseq) ⇒ Object?
Returns elements from self
; does not modify self
.
When a single Integer argument index
is given, returns the element at offset index
:
a = [:foo, 'bar', 2]
a[0] # => :foo
a[2] # => 2
a # => [:foo, "bar", 2]
If index
is negative, counts relative to the end of self
:
a = [:foo, 'bar', 2]
a[-1] # => 2
a[-2] # => "bar"
If index
is out of range, returns nil
.
When two Integer arguments start
and length
are given, returns a new Array of size length
containing successive elements beginning at offset start
:
a = [:foo, 'bar', 2]
a[0, 2] # => [:foo, "bar"]
a[1, 2] # => ["bar", 2]
If start + length
is greater than self.length
, returns all elements from offset start
to the end:
a = [:foo, 'bar', 2]
a[0, 4] # => [:foo, "bar", 2]
a[1, 3] # => ["bar", 2]
a[2, 2] # => [2]
If start == self.size
and length >= 0
, returns a new empty Array.
If length
is negative, returns nil
.
When a single Range argument range
is given, treats range.min
as start
above and range.size
as length
above:
a = [:foo, 'bar', 2]
a[0..1] # => [:foo, "bar"]
a[1..2] # => ["bar", 2]
Special case: If range.start == a.size
, returns a new empty Array.
If range.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]
If range.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]
If range.start
is larger than the array size, returns nil
.
a = [:foo, 'bar', 2]
a[4..1] # => nil
a[4..0] # => nil
a[4..-1] # => nil
When a single Enumerator::ArithmeticSequence argument aseq
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, throws RangeError.
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 to Integer, and raises if it is impossible:
a = [:foo, 'bar', 2]
# Raises TypeError (no implicit conversion of Symbol into Integer):
a[:foo]
Array#slice is an alias for Array#[].
1801 1802 1803 1804 1805 1806 1807 1808 1809 |
# File 'array.c', line 1801
VALUE
rb_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]);
}
|
#[]=(index) ⇒ Object #[]=(start, length) ⇒ Object #[]=(range) ⇒ Object
Assigns elements in self
; returns the given object
.
When Integer argument index
is given, assigns object
to an element in self
.
If index
is non-negative, assigns object
the element at offset index
:
a = [:foo, 'bar', 2]
a[0] = 'foo' # => "foo"
a # => ["foo", "bar", 2]
If index
is greater than self.length
, extends the array:
a = [:foo, 'bar', 2]
a[7] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]
If index
is negative, counts backwards from the end of the array:
a = [:foo, 'bar', 2]
a[-1] = 'two' # => "two"
a # => [:foo, "bar", "two"]
When Integer arguments start
and length
are given and object
is not an Array, removes length - 1
elements beginning at offset start
, and assigns object
at offset start
:
a = [:foo, 'bar', 2]
a[0, 2] = 'foo' # => "foo"
a # => ["foo", 2]
If start
is negative, counts backwards from the end of the array:
a = [:foo, 'bar', 2]
a[-2, 2] = 'foo' # => "foo"
a # => [:foo, "foo"]
If start
is non-negative and outside the array ( >= self.size
), extends the array with nil
, assigns object
at offset start
, and ignores length
:
a = [:foo, 'bar', 2]
a[6, 50] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
If length
is zero, shifts elements at and following offset start
and assigns object
at offset start
:
a = [:foo, 'bar', 2]
a[1, 0] = 'foo' # => "foo"
a # => [:foo, "foo", "bar", 2]
If length
is too large for the existing array, does not extend the array:
a = [:foo, 'bar', 2]
a[1, 5] = 'foo' # => "foo"
a # => [:foo, "foo"]
When Range argument range
is given and object
is an Array, removes length - 1
elements beginning at offset start
, and assigns object
at offset start
:
a = [:foo, 'bar', 2]
a[0..1] = 'foo' # => "foo"
a # => ["foo", 2]
if range.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 than range.begin
, assigns object
at offset range.begin
, and ignores length
:
a = [:foo, 'bar', 2]
a[6..50] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
If range.end
is zero, shifts elements at and following offset start
and assigns object
at offset start
:
a = [:foo, 'bar', 2]
a[1..0] = 'foo' # => "foo"
a # => [:foo, "foo", "bar", 2]
If range.end
is negative, assigns object
at offset start
, retains range.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]
If range.end
is too large for the existing array, replaces array elements, but does not extend the array with nil
values:
a = [:foo, 'bar', 2]
a[1..5] = 'foo' # => "foo"
a # => [:foo, "foo"]
2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 |
# File 'array.c', line 2388
static VALUE
rb_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]);
}
|
#all? ⇒ Boolean #all? {|element| ... } ⇒ Boolean #all?(obj) ⇒ Boolean
Returns true
if all elements of self
meet a given criterion.
With no block given and no argument, returns true
if self
contains only truthy elements, false
otherwise:
[0, 1, :foo].all? # => true
[0, nil, 2].all? # => false
[].all? # => true
With a block given and no argument, calls the block with each element in self
; returns true
if the block returns only truthy values, false
otherwise:
[0, 1, 2].all? { |element| element < 3 } # => true
[0, 1, 2].all? { |element| element < 2 } # => false
If argument obj
is given, returns true
if obj.===
every element, false
otherwise:
['food', 'fool', 'foot'].all?(/foo/) # => true
['food', 'drink'].all?(/bar/) # => false
[].all?(/foo/) # => true
[0, 0, 0].all?(0) # => true
[0, 1, 2].all?(1) # => false
Related: Enumerable#all?
7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 |
# File 'array.c', line 7476
static VALUE
rb_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;
}
|
#any? ⇒ Boolean #any? {|element| ... } ⇒ Boolean #any?(obj) ⇒ Boolean
Returns true
if any element of self
meets a given criterion.
With no block given and no argument, returns true
if self
has any truthy element, false
otherwise:
[nil, 0, false].any? # => true
[nil, false].any? # => false
[].any? # => false
With a block given and no argument, calls the block with each element in self
; returns true
if the block returns any truthy value, false
otherwise:
[0, 1, 2].any? {|element| element > 1 } # => true
[0, 1, 2].any? {|element| element > 2 } # => false
If argument obj
is given, returns true
if obj
.===
any element, false
otherwise:
['food', 'drink'].any?(/foo/) # => true
['food', 'drink'].any?(/bar/) # => false
[].any?(/foo/) # => false
[0, 1, 2].any?(1) # => true
[0, 1, 2].any?(3) # => false
Related: Enumerable#any?
7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 |
# File 'array.c', line 7419
static VALUE
rb_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;
}
|
#assoc(obj) ⇒ nil
Returns the first element in self
that is an Array whose first element ==
obj
:
a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
a.assoc(4) # => [4, 5, 6]
Returns nil
if no such element is found.
Related: #rassoc.
4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 |
# File 'array.c', line 4935
VALUE
rb_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;
}
|
#at(index) ⇒ Object
Returns the element at Integer offset index
; does not modify self
.
a = [:foo, 'bar', 2]
a.at(0) # => :foo
a.at(2) # => 2
1854 1855 1856 1857 1858 |
# File 'array.c', line 1854
VALUE
rb_ary_at(VALUE ary, VALUE pos)
{
return rb_ary_entry(ary, NUM2LONG(pos));
}
|
#bsearch {|element| ... } ⇒ Object #bsearch ⇒ Object
Returns an element from self
selected by a binary search. self
should be sorted, but this is not checked.
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.
There are two search modes:
-
Find-minimum mode: the block should return
true
orfalse
. -
Find-any mode: the block should return a numeric value.
The block should not mix the modes by and sometimes returning true
or false
and sometimes returning a numeric value, but this is not checked.
Find-Minimum Mode
In find-minimum mode, the block always returns true
or false
. The further requirement (though not checked) is that there are no indexes i
and j
such that:
-
0 <= i < j <= self.size
. -
The block returns
true
forself[i]
andfalse
forself[j]
.
In find-minimum mode, method bsearch returns the first element for which the block returns true.
Examples:
a = [0, 4, 7, 10, 12]
a.bsearch {|x| x >= 4 } # => 4
a.bsearch {|x| x >= 6 } # => 7
a.bsearch {|x| x >= -1 } # => 0
a.bsearch {|x| x >= 100 } # => nil
Less formally: the block is such that all false
-evaluating elements precede all true
-evaluating elements.
These make sense as blocks in find-minimum mode:
a = [0, 4, 7, 10, 12]
a.map {|x| x >= 4 } # => [false, true, true, true, true]
a.map {|x| x >= 6 } # => [false, false, true, true, true]
a.map {|x| x >= -1 } # => [true, true, true, true, true]
a.map {|x| x >= 100 } # => [false, false, false, false, false]
This would not make sense:
a = [0, 4, 7, 10, 12]
a.map {|x| x == 7 } # => [false, false, true, false, false]
Find-Any Mode
In find-any mode, the block always returns a numeric value. The further requirement (though not checked) is that there are no indexes i
and j
such that:
-
0 <= i < j <= self.size
. -
The block returns a negative value for
self[i]
and a positive value forself[j]
. -
The block returns a negative value for
self[i]
and zeroself[j]
. -
The block returns zero for
self[i]
and a positive value forself[j]
.
In find-any mode, method bsearch returns some element for which the block returns zero, or nil
if no such element is found.
Examples:
a = [0, 4, 7, 10, 12]
a.bsearch {|element| 7 <=> element } # => 7
a.bsearch {|element| -1 <=> element } # => nil
a.bsearch {|element| 5 <=> element } # => nil
a.bsearch {|element| 15 <=> element } # => nil
Less formally: the block is such that:
-
All positive-evaluating elements precede all zero-evaluating elements.
-
All positive-evaluating elements precede all negative-evaluating elements.
-
All zero-evaluating elements precede all negative-evaluating elements.
These make sense as blocks in find-any mode:
a = [0, 4, 7, 10, 12]
a.map {|element| 7 <=> element } # => [1, 1, 0, -1, -1]
a.map {|element| -1 <=> element } # => [-1, -1, -1, -1, -1]
a.map {|element| 5 <=> element } # => [1, 1, -1, -1, -1]
a.map {|element| 15 <=> element } # => [1, 1, 1, 1, 1]
This would not make sense:
a = [0, 4, 7, 10, 12]
a.map {|element| element <=> 7 } # => [-1, -1, 0, 1, 1]
Returns an enumerator if no block given:
a = [0, 4, 7, 10, 12]
a.bsearch # => #<Enumerator: [0, 4, 7, 10, 12]:bsearch>
3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 |
# File 'array.c', line 3496
static VALUE
rb_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;
}
|
#bsearch_index {|element| ... } ⇒ Integer? #bsearch_index ⇒ Object
Searches self
as described at method #bsearch, but returns the index of the found element instead of the element itself.
3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 |
# File 'array.c', line 3516
static VALUE
rb_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 (v == Qfalse || v == Qnil) {
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 = 1; break;
case -1: smaller = 0;
}
}
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);
}
|
#clear ⇒ self
Removes all elements from self
:
a = [:foo, 'bar', 2]
a.clear # => []
4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 |
# File 'array.c', line 4532
VALUE
rb_ary_clear(VALUE ary)
{
rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
if (!ARY_EMBED_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;
}
|
#map {|element| ... } ⇒ Object #map ⇒ Object
Calls the block, if given, with each element of self
; 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]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2]
a1 = a.map
a1 # => #<Enumerator: [:foo, "bar", 2]:map>
Array#collect is an alias for Array#map.
3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 |
# File 'array.c', line 3626
static VALUE
rb_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;
}
|
#map! {|element| ... } ⇒ self #map! ⇒ Object
Calls the block, if given, with each element; replaces the element with the block’s return value:
a = [:foo, 'bar', 2]
a.map! { |element| element.class } # => [Symbol, String, Integer]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2]
a1 = a.map!
a1 # => #<Enumerator: [:foo, "bar", 2]:map!>
Array#collect! is an alias for Array#map!.
3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 |
# File 'array.c', line 3659
static VALUE
rb_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;
}
|
#combination(n) {|element| ... } ⇒ self #combination(n) ⇒ Object
Calls the block, if given, with combinations of elements of self
; returns self
. The order of combinations is indeterminate.
When a block and an in-range positive Integer argument n
(0 < n <= self.size
) are given, calls the block with all n
-tuple combinations of self
.
Example:
a = [0, 1, 2]
a.combination(2) {|combination| p combination }
Output:
[0, 1]
[0, 2]
[1, 2]
Another example:
a = [0, 1, 2]
a.combination(3) {|combination| p combination }
Output:
[0, 1, 2]
When n
is zero, calls the block once with a new empty Array:
a = [0, 1, 2]
a1 = a.combination(0) {|combination| p combination }
Output:
[]
When n
is out of range (negative or larger than self.size
), does not call the block:
a = [0, 1, 2]
a.combination(-1) {|combination| fail 'Cannot happen' }
a.combination(4) {|combination| fail 'Cannot happen' }
Returns a new Enumerator if no block given:
a = [0, 1, 2]
a.combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 |
# File 'array.c', line 6843
static VALUE
rb_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;
}
|
#compact ⇒ Object
Returns a new Array containing all non-nil
elements from self
:
a = [nil, 0, nil, 1, nil, 2, nil]
a.compact # => [0, 1, 2]
6066 6067 6068 6069 6070 6071 6072 |
# File 'array.c', line 6066
static VALUE
rb_ary_compact(VALUE ary)
{
ary = rb_ary_dup(ary);
rb_ary_compact_bang(ary);
return ary;
}
|
#compact! ⇒ self?
Removes all nil
elements from self
.
Returns self
if any elements removed, otherwise nil
.
6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 |
# File 'array.c', line 6034
static VALUE
rb_ary_compact_bang(VALUE ary)
{
VALUE *p, *t, *end;
long n;
rb_ary_modify(ary);
p = t = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(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_TRANSIENT(ary);
if (RARRAY_LEN(ary) == n) {
return Qnil;
}
ary_resize_smaller(ary, n);
return ary;
}
|
#concat(*other_arrays) ⇒ self
Adds to array
all elements from each Array in other_arrays
; returns self
:
a = [0, 1]
a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5]
4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 |
# File 'array.c', line 4835
static VALUE
rb_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_tmp_new(argc);
for (i = 0; i < argc; i++) {
rb_ary_concat(args, argv[i]);
}
ary_append(ary, args);
}
ary_verify(ary);
return ary;
}
|
#count ⇒ Integer #count(obj) ⇒ Integer #count {|element| ... } ⇒ Integer
Returns a count of specified elements.
With no argument and no block, returns the count of all elements:
[0, 1, 2].count # => 3
[].count # => 0
With argument obj
, returns the count of elements eql?
to obj
:
[0, 1, 2, 0].count(0) # => 2
[0, 1, 2].count(3) # => 0
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 argument obj
and a block given, issues a warning, ignores the block, and returns the count of elements eql?
to obj
:
6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 |
# File 'array.c', line 6098
static VALUE
rb_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);
}
|
#cycle {|element| ... } ⇒ nil #cycle(count) {|element| ... } ⇒ nil #cycle ⇒ Object #cycle(count) ⇒ Object
When called with positive Integer argument count
and a block, calls the block with each element, then does so again, until it has done so count
times; returns nil
:
output = []
[0, 1].cycle(2) {|element| output.push(element) } # => nil
output # => [0, 1, 0, 1]
If count
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
When a block is given, and argument is omitted or nil
, cycles forever:
# Prints 0 and 1 forever.
[0, 1].cycle {|element| puts element }
[0, 1].cycle(nil) {|element| puts element }
When no block is given, returns a new Enumerator:
[0, 1].cycle(2) # => #<Enumerator: [0, 1]:cycle(2)>
[0, 1].cycle # => # => #<Enumerator: [0, 1]:cycle>
[0, 1].cycle.first(5) # => [0, 1, 0, 1, 0]
6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 |
# File 'array.c', line 6526
static VALUE
rb_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;
}
|
#deconstruct ⇒ Object
7816 7817 7818 7819 7820 |
# File 'array.c', line 7816
static VALUE
rb_ary_deconstruct(VALUE ary)
{
return ary;
}
|
#delete(obj) ⇒ Object #delete(obj) {|nosuch| ... } ⇒ Object
Removes zero or more elements from self
; returns self
.
When no block is given, removes from self
each element ele
such that ele == obj
; returns the last deleted element:
s1 = 'bar'; s2 = 'bar'
a = [:foo, s1, 2, s2]
a.delete('bar') # => "bar"
a # => [:foo, 2]
Returns nil
if no elements removed.
When a block is given, removes from self
each element ele
such that ele == obj
.
If any such elements are found, ignores the block and returns the last deleted element:
s1 = 'bar'; s2 = 'bar'
a = [:foo, s1, 2, s2]
deleted_obj = a.delete('bar') {|obj| fail 'Cannot happen' }
a # => [:foo, 2]
If no such elements are found, returns the block’s return value:
a = [:foo, 'bar', 2]
a.delete(:nosuch) {|obj| "#{obj} not found" } # => "nosuch not found"
3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 |
# File 'array.c', line 3954
VALUE
rb_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;
}
|
#delete_at(index) ⇒ nil
Deletes an element from self
, per the given Integer index
.
When index
is non-negative, deletes the element at offset index
:
a = [:foo, 'bar', 2]
a.delete_at(1) # => "bar"
a # => [:foo, 2]
If index is too large, returns nil
.
When index
is negative, counts backward from the end of the array:
a = [:foo, 'bar', 2]
a.delete_at(-2) # => "bar"
a # => [:foo, 2]
If index
is too small (far from zero), returns nil.
4051 4052 4053 4054 4055 |
# File 'array.c', line 4051
static VALUE
rb_ary_delete_at_m(VALUE ary, VALUE pos)
{
return rb_ary_delete_at(ary, NUM2LONG(pos));
}
|
#delete_if {|element| ... } ⇒ self #delete_if ⇒ Enumerator
Removes each element in self
for which the block returns a truthy value; returns self
:
a = [:foo, 'bar', 2, 'bat']
a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2]
a.delete_if # => #<Enumerator: [:foo, "bar", 2]:delete_if>
4292 4293 4294 4295 4296 4297 4298 4299 |
# File 'array.c', line 4292
static VALUE
rb_ary_delete_if(VALUE ary)
{
ary_verify(ary);
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
ary_reject_bang(ary);
return ary;
}
|
#difference(*other_arrays) ⇒ Object
Returns a new Array containing only those elements from self
that are not found in any of the Arrays other_arrays
; items are compared using eql?
; order from self
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]
Returns a copy of self
if no arguments given.
Related: Array#-.
5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 |
# File 'array.c', line 5330
static VALUE
rb_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], RARRAY_AREF(ary, i), 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;
}
|
#dig(index, *identifiers) ⇒ Object
Finds and returns the object in nested objects that is specified by index
and identifiers
. The nested objects may be instances of various classes. See Dig 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) # => :bat
a.dig(1, 2, 3) # => nil
7649 7650 7651 7652 7653 7654 7655 7656 7657 |
# File 'array.c', line 7649
static VALUE
rb_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);
}
|
#drop(n) ⇒ Object
Returns a new Array containing all but the first n
element of self
, where n
is a non-negative Integer; does not modify self
.
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]
7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 |
# File 'array.c', line 7345
static VALUE
rb_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 (result == Qnil) result = rb_ary_new();
return result;
}
|
#drop_while {|element| ... } ⇒ Object #drop_while ⇒ Object
Returns a new Array containing zero or more trailing elements of self
; does not modify self
.
With a block given, calls the block with each successive element of self
; stops if the block returns false
or nil
; returns a new Array omitting those elements for which the block returned a truthy value:
a = [0, 1, 2, 3, 4, 5]
a.drop_while {|element| element < 3 } # => [3, 4, 5]
With no block given, returns a new Enumerator:
[0, 1].drop_while # => # => #<Enumerator: [0, 1]:drop_while>
7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 |
# File 'array.c', line 7377
static VALUE
rb_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));
}
|
#each {|element| ... } ⇒ self #each ⇒ Enumerator
Iterates over array elements.
When a block given, passes each successive array element to the block; returns self
:
a = [:foo, 'bar', 2]
a.each {|element| puts "#{element.class} #{element}" }
Output:
Symbol foo
String
Integer 2
Allows the array to be modified during iteration:
a = [:foo, 'bar', 2]
a.each {|element| puts element; a.clear if element.to_s.start_with?('b') }
Output:
foo
When no block given, returns a new Enumerator:
a = [:foo, 'bar', 2]
e = a.each
e # => #<Enumerator: [:foo, "bar", 2]:each>
a1 = e.each {|element| puts "#{element.class} #{element}" }
Output:
Symbol foo
String
Integer 2
Related: #each_index, #reverse_each.
2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 |
# File 'array.c', line 2516
VALUE
rb_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;
}
|
#each_index {|index| ... } ⇒ self #each_index ⇒ Enumerator
Iterates over array indexes.
When a block given, passes each successive array index to the block; returns self
:
a = [:foo, 'bar', 2]
a.each_index {|index| puts "#{index} #{a[index]}" }
Output:
0 foo
1 bar
2 2
Allows the array to be modified during iteration:
a = [:foo, 'bar', 2]
a.each_index {|index| puts index; a.clear if index > 0 }
Output:
0
1
When no block given, returns a new Enumerator:
a = [:foo, 'bar', 2]
e = a.each_index
e # => #<Enumerator: [:foo, "bar", 2]:each_index>
a1 = e.each {|index| puts "#{index} #{a[index]}"}
Output:
0 foo
1 bar
2 2
Related: #each, #reverse_each.
2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 |
# File 'array.c', line 2567
static VALUE
rb_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;
}
|
#empty? ⇒ Boolean
Returns true
if the count of elements in self
is zero, false
otherwise.
2657 2658 2659 2660 2661 2662 2663 |
# File 'array.c', line 2657
static VALUE
rb_ary_empty_p(VALUE ary)
{
if (RARRAY_LEN(ary) == 0)
return Qtrue;
return Qfalse;
}
|
#eql?(other_array) ⇒ Boolean
Returns true
if self
and other_array
are the same size, and if, for each index i
in self
, self[i].eql? other_array[i]
:
a0 = [:foo, 'bar', 2]
a1 = [:foo, 'bar', 2]
a1.eql?(a0) # => true
Otherwise, returns false
.
This method is different from method Array#==, which compares using method Object#==
.
5075 5076 5077 5078 5079 5080 5081 5082 5083 |
# File 'array.c', line 5075
static VALUE
rb_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_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue;
return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
}
|
#fetch(index) ⇒ Object #fetch(index, default_value) ⇒ Object #fetch(index) {|index| ... } ⇒ Object
Returns the element at offset index
.
With the single Integer argument index
, returns the element at offset index
:
a = [:foo, 'bar', 2]
a.fetch(1) # => "bar"
If index
is negative, counts from the end of the array:
a = [:foo, 'bar', 2]
a.fetch(-1) # => 2
a.fetch(-2) # => "bar"
With arguments index
and default_value
, returns the element at offset index
if index is in range, otherwise returns default_value
:
a = [:foo, 'bar', 2]
a.fetch(1, nil) # => "bar"
With argument index
and a block, returns the element at offset index
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"
1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 |
# File 'array.c', line 1977
static VALUE
rb_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);
}
|
#fill(obj) ⇒ self #fill(obj, start) ⇒ self #fill(obj, start, length) ⇒ self #fill(obj, range) ⇒ self #fill {|index| ... } ⇒ self #fill(start) {|index| ... } ⇒ self #fill(start, length) {|index| ... } ⇒ self #fill(range) {|index| ... } ⇒ self
Replaces specified elements in self
with specified objects; returns self
.
With argument obj
and no block given, replaces all elements with that one object:
a = ['a', 'b', 'c', 'd']
a # => ["a", "b", "c", "d"]
a.fill(:X) # => [:X, :X, :X, :X]
With arguments obj
and Integer start
, and no block given, replaces elements based on the given start.
If start
is in range (0 <= start < array.size
), replaces all elements from offset start
through the end:
a = ['a', 'b', 'c', 'd']
a.fill(:X, 2) # => ["a", "b", :X, :X]
If start
is too large (start >= array.size
), does nothing:
a = ['a', 'b', 'c', 'd']
a.fill(:X, 4) # => ["a", "b", "c", "d"]
a = ['a', 'b', 'c', 'd']
a.fill(:X, 5) # => ["a", "b", "c", "d"]
If start
is negative, counts from the end (starting index is start + array.size
):
a = ['a', 'b', 'c', 'd']
a.fill(:X, -2) # => ["a", "b", :X, :X]
If start
is too small (less than and far from zero), replaces all elements:
a = ['a', 'b', 'c', 'd']
a.fill(:X, -6) # => [:X, :X, :X, :X]
a = ['a', 'b', 'c', 'd']
a.fill(:X, -50) # => [:X, :X, :X, :X]
With arguments obj
, Integer start
, and Integer length
, and no block given, replaces elements based on the given start
and length
.
If start
is in range, replaces length
elements beginning at offset start
:
a = ['a', 'b', 'c', 'd']
a.fill(:X, 1, 1) # => ["a", :X, "c", "d"]
If start
is negative, counts from the end:
a = ['a', 'b', 'c', 'd']
a.fill(:X, -2, 1) # => ["a", "b", :X, "d"]
If start
is large (start >= array.size
), extends self
with nil
:
a = ['a', 'b', 'c', 'd']
a.fill(:X, 5, 0) # => ["a", "b", "c", "d", nil]
a = ['a', 'b', 'c', 'd']
a.fill(:X, 5, 2) # => ["a", "b", "c", "d", nil, :X, :X]
If length
is zero or negative, replaces no elements:
a = ['a', 'b', 'c', 'd']
a.fill(:X, 1, 0) # => ["a", "b", "c", "d"]
a.fill(:X, 1, -1) # => ["a", "b", "c", "d"]
With arguments obj
and Range range
, and no block given, replaces elements based on the given range.
If the range is positive and ascending (0 < range.begin <= range.end
), replaces elements from range.begin
to range.end
:
a = ['a', 'b', 'c', 'd']
a.fill(:X, (1..1)) # => ["a", :X, "c", "d"]
If range.first
is negative, replaces no elements:
a = ['a', 'b', 'c', 'd']
a.fill(:X, (-1..1)) # => ["a", "b", "c", "d"]
If range.last
is negative, counts from the end:
a = ['a', 'b', 'c', 'd']
a.fill(:X, (0..-2)) # => [:X, :X, :X, "d"]
a = ['a', 'b', 'c', 'd']
a.fill(:X, (1..-2)) # => ["a", :X, :X, "d"]
If range.last
and range.last
are both negative, both count from the end of the array:
a = ['a', 'b', 'c', 'd']
a.fill(:X, (-1..-1)) # => ["a", "b", "c", :X]
a = ['a', 'b', 'c', 'd']
a.fill(:X, (-2..-2)) # => ["a", "b", :X, "d"]
With no arguments and a block given, calls the block with each index; replaces the corresponding element with the block’s return value:
a = ['a', 'b', 'c', 'd']
a.fill { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
With argument start
and a block given, calls the block with each index from offset start
to the end; replaces the corresponding element with the block’s return value:
If start is in range (0 <= start < array.size
), replaces from offset start
to the end:
a = ['a', 'b', 'c', 'd']
a.fill(1) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "new_3"]
If start
is too large(start >= array.size
), does nothing:
a = ['a', 'b', 'c', 'd']
a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
a = ['a', 'b', 'c', 'd']
a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
If start
is negative, counts from the end:
a = ['a', 'b', 'c', 'd']
a.fill(-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "new_3"]
If start is too small (start <= -array.size
, replaces all elements:
a = ['a', 'b', 'c', 'd']
a.fill(-6) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
a = ['a', 'b', 'c', 'd']
a.fill(-50) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"]
With arguments start
and length
, and a block given, calls the block for each index specified by start length; replaces the corresponding element with the block’s return value.
If start
is in range, replaces length
elements beginning at offset start
:
a = ['a', 'b', 'c', 'd']
a.fill(1, 1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"]
If start is negative, counts from the end:
a = ['a', 'b', 'c', 'd']
a.fill(-2, 1) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"]
If start
is large (start >= array.size
), extends self
with nil
:
a = ['a', 'b', 'c', 'd']
a.fill(5, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil]
a = ['a', 'b', 'c', 'd']
a.fill(5, 2) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil, "new_5", "new_6"]
If length
is zero or less, replaces no elements:
a = ['a', 'b', 'c', 'd']
a.fill(1, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d"]
a.fill(1, -1) { |index| "new_#{index}" } # => ["a", "b", "c", "d"]
With arguments obj
and range
, and a block given, calls the block with each index in the given range; replaces the corresponding element with the block’s return value.
If the range is positive and ascending (range 0 < range.begin <= range.end
, replaces elements from range.begin
to range.end
:
a = ['a', 'b', 'c', 'd']
a.fill(1..1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"]
If range.first
is negative, does nothing:
a = ['a', 'b', 'c', 'd']
a.fill(-1..1) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
If range.last
is negative, counts from the end:
a = ['a', 'b', 'c', 'd']
a.fill(0..-2) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "d"]
a = ['a', 'b', 'c', 'd']
a.fill(1..-2) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "d"]
If range.first
and range.last
are both negative, both count from the end:
a = ['a', 'b', 'c', 'd']
a.fill(-1..-1) { |index| "new_#{index}" } # => ["a", "b", "c", "new_3"]
a = ['a', 'b', 'c', 'd']
a.fill(-2..-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"]
4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 |
# File 'array.c', line 4722
static VALUE
rb_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 (item == Qundef) {
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;
}
|
#select {|element| ... } ⇒ Object #select ⇒ Object
Calls the block, if given, with each element of self
; returns a new Array containing those elements of self
for which the block returns a truthy value:
a = [:foo, 'bar', 2, :bam]
a1 = a.select {|element| element.to_s.start_with?('b') }
a1 # => ["bar", :bam]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2, :bam]
a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select>
Array#filter is an alias for Array#select.
3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 |
# File 'array.c', line 3792
static VALUE
rb_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;
}
|
#select! {|element| ... } ⇒ self? #select! ⇒ Object
Calls the block, if given with each element of self
; removes from self
those elements for which the block returns false
or nil
.
Returns self
if any elements were removed:
a = [:foo, 'bar', 2, :bam]
a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
Returns nil
if no elements were removed.
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2, :bam]
a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!>
Array#filter! is an alias for Array#select!.
3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 |
# File 'array.c', line 3873
static VALUE
rb_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);
}
|
#index(object) ⇒ Integer? #index {|element| ... } ⇒ Integer? #index ⇒ Object
Returns the index of a specified element.
When argument object
is given but no block, returns the index of the first element element
for which object == element
:
a = [:foo, 'bar', 2, 'bar']
a.index('bar') # => 1
Returns nil
if no such element found.
When both argument object
and a block are 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
Returns nil
if the block never returns a truthy value.
When neither an argument nor a block is given, returns a new Enumerator:
a = [:foo, 'bar', 2]
e = a.index
e # => #<Enumerator: [:foo, "bar", 2]:index>
e.each {|element| element == 'bar' } # => 1
Array#find_index is an alias for Array#index.
Related: #rindex.
2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 |
# File 'array.c', line 2040
static VALUE
rb_ary_index(int argc, VALUE *argv, VALUE ary)
{
VALUE val;
long i;
if (argc == 0) {
RETURN_ENUMERATOR(ary, 0, 0);
for (i=0; i<RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
return LONG2NUM(i);
}
}
return Qnil;
}
rb_check_arity(argc, 0, 1);
val = argv[0];
if (rb_block_given_p())
rb_warn("given block not used");
for (i=0; i<RARRAY_LEN(ary); i++) {
VALUE e = RARRAY_AREF(ary, i);
if (rb_equal(e, val)) {
return LONG2NUM(i);
}
}
return Qnil;
}
|
#first ⇒ Object? #first(n) ⇒ Object
Returns elements from self
; does not modify self
.
When no argument is given, returns the first element:
a = [:foo, 'bar', 2]
a.first # => :foo
a # => [:foo, "bar", 2]
If self
is empty, returns nil
.
When non-negative Integer argument n
is given, returns the first n
elements in a new Array:
a = [:foo, 'bar', 2]
a.first(2) # => [:foo, "bar"]
If n >= array.size
, returns all elements:
a = [:foo, 'bar', 2]
a.first(50) # => [:foo, "bar", 2]
If n == 0
returns an new empty Array:
a = [:foo, 'bar', 2]
a.first(0) # []
Related: #last.
1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 |
# File 'array.c', line 1889
static VALUE
rb_ary_first(int argc, VALUE *argv, VALUE ary)
{
if (argc == 0) {
if (RARRAY_LEN(ary) == 0) return Qnil;
return RARRAY_AREF(ary, 0);
}
else {
return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
}
}
|
#flatten ⇒ Object #flatten(level) ⇒ Object
Returns a new Array that is a recursive flattening of self
:
-
Each non-Array element is unchanged.
-
Each Array is replaced by its individual elements.
With non-negative Integer argument level
, flattens recursively through level
levels:
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten(0) # => [0, [1, [2, 3], 4], 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten(1) # => [0, 1, [2, 3], 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten(2) # => [0, 1, 2, 3, 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten(3) # => [0, 1, 2, 3, 4, 5]
With no argument, a nil
argument, or with negative argument level
, flattens all levels:
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten # => [0, 1, 2]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten(-1) # => [0, 1, 2, 3, 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten(-2) # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten(-1) # => [0, 1, 2]
6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 |
# File 'array.c', line 6300
static VALUE
rb_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;
}
|
#flatten! ⇒ self? #flatten!(level) ⇒ self?
Replaces each nested Array in self
with the elements from that Array; returns self
if any changes, nil
otherwise.
With non-negative Integer argument level
, flattens recursively through level
levels:
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(1) # => [0, 1, [2, 3], 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(2) # => [0, 1, 2, 3, 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(3) # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten!(1) # => nil
With no argument, a nil
argument, or with negative argument level
, flattens all levels:
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten! # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten! # => nil
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(-1) # => [0, 1, 2, 3, 4, 5]
a = [ 0, [ 1, [2, 3], 4 ], 5 ]
a.flatten!(-2) # => [0, 1, 2, 3, 4, 5]
[0, 1, 2].flatten!(-1) # => nil
6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 |
# File 'array.c', line 6248
static VALUE
rb_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_obj_freeze(result);
rb_ary_replace(ary, result);
if (mod) ARY_SET_EMBED_LEN(result, 0);
return ary;
}
|
#hash ⇒ Integer
Returns the integer hash value for self
.
Two arrays with the same content will have the same hash code (and will compare using eql?):
[0, 1, 2].hash == [0, 1, 2].hash # => true
[0, 1, 2].hash == [0, 1, 3].hash # => false
5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 |
# File 'array.c', line 5096
static VALUE
rb_ary_hash(VALUE ary)
{
long i;
st_index_t h;
VALUE n;
h = rb_hash_start(RARRAY_LEN(ary));
h = rb_hash_uint(h, (st_index_t)rb_ary_hash);
for (i=0; i<RARRAY_LEN(ary); i++) {
n = rb_hash(RARRAY_AREF(ary, i));
h = rb_hash_uint(h, NUM2LONG(n));
}
h = rb_hash_end(h);
return ST2FIX(h);
}
|
#include?(obj) ⇒ Boolean
Returns true
if for some index i
in self
, obj == self[i]
; otherwise false
:
[0, 1, 2].include?(2) # => true
[0, 1, 2].include?(3) # => false
5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 |
# File 'array.c', line 5123
VALUE
rb_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;
}
|
#index(object) ⇒ Integer? #index {|element| ... } ⇒ Integer? #index ⇒ Object
Returns the index of a specified element.
When argument object
is given but no block, returns the index of the first element element
for which object == element
:
a = [:foo, 'bar', 2, 'bar']
a.index('bar') # => 1
Returns nil
if no such element found.
When both argument object
and a block are 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
Returns nil
if the block never returns a truthy value.
When neither an argument nor a block is given, returns a new Enumerator:
a = [:foo, 'bar', 2]
e = a.index
e # => #<Enumerator: [:foo, "bar", 2]:index>
e.each {|element| element == 'bar' } # => 1
Array#find_index is an alias for Array#index.
Related: #rindex.
2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 |
# File 'array.c', line 2040
static VALUE
rb_ary_index(int argc, VALUE *argv, VALUE ary)
{
VALUE val;
long i;
if (argc == 0) {
RETURN_ENUMERATOR(ary, 0, 0);
for (i=0; i<RARRAY_LEN(ary); i++) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
return LONG2NUM(i);
}
}
return Qnil;
}
rb_check_arity(argc, 0, 1);
val = argv[0];
if (rb_block_given_p())
rb_warn("given block not used");
for (i=0; i<RARRAY_LEN(ary); i++) {
VALUE e = RARRAY_AREF(ary, i);
if (rb_equal(e, val)) {
return LONG2NUM(i);
}
}
return Qnil;
}
|
#replace(other_array) ⇒ self
Replaces the content of self
with the content of other_array
; returns self
:
a = [:foo, 'bar', 2]
a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3]
4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 |
# File 'array.c', line 4482
VALUE
rb_ary_replace(VALUE copy, VALUE orig)
{
rb_ary_modify_check(copy);
orig = to_ary(orig);
if (copy == orig) return copy;
if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
VALUE shared_root = 0;
if (ARY_OWNS_HEAP_P(copy)) {
ary_heap_free(copy);
}
else if (ARY_SHARED_P(copy)) {
shared_root = ARY_SHARED_ROOT(copy);
FL_UNSET_SHARED(copy);
}
FL_SET_EMBED(copy);
ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
if (shared_root) {
rb_ary_decrement_share(shared_root);
}
ARY_SET_LEN(copy, RARRAY_LEN(orig));
}
else {
VALUE shared_root = ary_make_shared(orig);
if (ARY_OWNS_HEAP_P(copy)) {
ary_heap_free(copy);
}
else {
rb_ary_unshare_safe(copy);
}
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);
}
ary_verify(copy);
return copy;
}
|
#insert(index, *objects) ⇒ self
Inserts given objects
before or after the element at Integer index offset
; returns self
.
When index
is non-negative, inserts all given objects
before the element at offset index
:
a = [:foo, 'bar', 2]
a.insert(1, :bat, :bam) # => [:foo, :bat, :bam, "bar", 2]
Extends the array if index
is beyond the array (index >= self.size
):
a = [:foo, 'bar', 2]
a.insert(5, :bat, :bam)
a # => [:foo, "bar", 2, nil, nil, :bat, :bam]
Does nothing if no objects given:
a = [:foo, 'bar', 2]
a.insert(1)
a.insert(50)
a.insert(-50)
a # => [:foo, "bar", 2]
When index
is negative, inserts all given objects
after the element at offset index+self.size
:
a = [:foo, 'bar', 2]
a.insert(-2, :bat, :bam)
a # => [:foo, "bar", :bat, :bam, 2]
2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 |
# File 'array.c', line 2444
static VALUE
rb_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;
}
|
#inspect ⇒ Object Also known as: to_s
Returns the new String formed by calling method #inspect
on each array element:
a = [:foo, 'bar', 2]
a.inspect # => "[:foo, \"bar\", 2]"
Array#to_s is an alias for Array#inspect.
2886 2887 2888 2889 2890 2891 |
# File 'array.c', line 2886
static VALUE
rb_ary_inspect(VALUE ary)
{
if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
return rb_exec_recursive(inspect_ary, ary, 0);
}
|
#intersection(*other_arrays) ⇒ Object
Returns a new Array containing each element found both in self
and in all of the given Arrays other_arrays
; duplicates are omitted; items are compared using eql?
:
[0, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
[0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
Preserves order from self
:
[0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2]
Returns a copy of self
if no arguments given.
Related: Array#&.
5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 |
# File 'array.c', line 5436
static VALUE
rb_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;
}
|
#- ⇒ Object #join(separator = $,) ⇒ Object
Returns the new String formed by joining the array elements after conversion. For each element element
-
Uses
element.to_s
ifelement
is not akind_of?(Array)
. -
Uses recursive
element.join(separator)
ifelement
is akind_of?(Array)
.
With no argument, joins using the output field separator, $,
:
a = [:foo, 'bar', 2]
$, # => nil
a.join # => "foobar2"
With string argument separator
, 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"
2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 |
# File 'array.c', line 2841
static VALUE
rb_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);
}
|
#keep_if {|element| ... } ⇒ self #keep_if ⇒ Object
Retains those elements for which the block returns a truthy value; deletes all other elements; returns self
:
a = [:foo, 'bar', 2, :bam]
a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2, :bam]
a.keep_if # => #<Enumerator: [:foo, "bar", 2, :bam]:keep_if>
3901 3902 3903 3904 3905 3906 3907 |
# File 'array.c', line 3901
static VALUE
rb_ary_keep_if(VALUE ary)
{
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_select_bang(ary);
return ary;
}
|
#last ⇒ Object? #last(n) ⇒ Object
Returns elements from self
; self
is not modified.
When no argument is given, returns the last element:
a = [:foo, 'bar', 2]
a.last # => 2
a # => [:foo, "bar", 2]
If self
is empty, returns nil
.
When non-negative Innteger argument n
is given, returns the last n
elements in a new Array:
a = [:foo, 'bar', 2]
a.last(2) # => ["bar", 2]
If n >= array.size
, returns all elements:
a = [:foo, 'bar', 2]
a.last(50) # => [:foo, "bar", 2]
If n == 0
, returns an new empty Array:
a = [:foo, 'bar', 2]
a.last(0) # []
Related: #first.
1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 |
# File 'array.c', line 1931
VALUE
rb_ary_last(int argc, const VALUE *argv, VALUE ary)
{
if (argc == 0) {
long len = RARRAY_LEN(ary);
if (len == 0) return Qnil;
return RARRAY_AREF(ary, len-1);
}
else {
return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
}
}
|
#length ⇒ Integer Also known as: size
Returns the count of elements in self
.
2642 2643 2644 2645 2646 2647 |
# File 'array.c', line 2642
static VALUE
rb_ary_length(VALUE ary)
{
long len = RARRAY_LEN(ary);
return LONG2NUM(len);
}
|
#map {|element| ... } ⇒ Object #map ⇒ Object
Calls the block, if given, with each element of self
; 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]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2]
a1 = a.map
a1 # => #<Enumerator: [:foo, "bar", 2]:map>
Array#collect is an alias for Array#map.
3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 |
# File 'array.c', line 3626
static VALUE
rb_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;
}
|
#map! {|element| ... } ⇒ self #map! ⇒ Object
Calls the block, if given, with each element; replaces the element with the block’s return value:
a = [:foo, 'bar', 2]
a.map! { |element| element.class } # => [Symbol, String, Integer]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2]
a1 = a.map!
a1 # => #<Enumerator: [:foo, "bar", 2]:map!>
Array#collect! is an alias for Array#map!.
3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 |
# File 'array.c', line 3659
static VALUE
rb_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;
}
|
#max ⇒ Object #max {|a, b| ... } ⇒ Object #max(n) ⇒ Object #max(n) {|a, b| ... } ⇒ Object
Returns one of the following:
-
The maximum-valued element from
self
. -
A new Array of maximum-valued elements selected from
self
.
When no block is given, each element in self
must respond to method <=>
with an Integer.
With no argument and no block, returns the element in self
having the maximum value per method <=>
:
[0, 1, 2].max # => 2
With an argument Integer n
and no block, returns a new Array with at most n
elements, in descending order per method <=>
:
[0, 1, 2, 3].max(3) # => [3, 2, 1]
[0, 1, 2, 3].max(6) # => [3, 2, 1]
When a block is given, the block must return an Integer.
With a block and no argument, calls the block self.size-1
times to compare elements; returns the element having the maximum value per the block:
['0', '00', '000'].max {|a, b| a.size <=> b.size } # => "000"
With an argument n
and a block, returns a new Array with at most n
elements, in descending order per the block:
['0', '00', '000'].max(2) {|a, b| a.size <=> b.size } # => ["000", "00"]
5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 |
# File 'array.c', line 5682
static VALUE
rb_ary_max(int argc, VALUE *argv, VALUE ary)
{
struct cmp_opt_data cmp_opt = { 0, 0 };
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 (result == Qundef || 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(cmp_opt, Integer)) {
return ary_max_opt_fixnum(ary, 1, result);
}
else if (STRING_P(result) && CMP_OPTIMIZABLE(cmp_opt, String)) {
return ary_max_opt_string(ary, 1, result);
}
else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(cmp_opt, Float)) {
return ary_max_opt_float(ary, 1, result);
}
else {
return ary_max_generic(ary, 1, result);
}
}
}
if (result == Qundef) return Qnil;
return result;
}
|
#min ⇒ Object #min {|a, b| ... } ⇒ Object #min(n) ⇒ Object #min(n) {|a, b| ... } ⇒ Object
Returns one of the following:
-
The minimum-valued element from
self
. -
A new Array of minimum-valued elements selected from
self
.
When no block is given, each element in self
must respond to method <=>
with an Integer.
With no argument and no block, returns the element in self
having the minimum value per method <=>
:
[0, 1, 2].min # => 0
With Integer argument n
and no block, returns a new Array with at most n
elements, in ascending order per method <=>
:
[0, 1, 2, 3].min(3) # => [0, 1, 2]
[0, 1, 2, 3].min(6) # => [0, 1, 2, 3]
When a block is given, the block must return an Integer.
With a block and no argument, calls the block self.size-1
times to compare elements; returns the element having the minimum value per the block:
['0', '00', '000'].min { |a, b| a.size <=> b.size } # => "0"
With an argument n
and a block, returns a new Array with at most n
elements, in ascending order per the block:
[0, 1, 2, 3].min(3) # => [0, 1, 2]
[0, 1, 2, 3].min(6) # => [0, 1, 2, 3]
5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 |
# File 'array.c', line 5846
static VALUE
rb_ary_min(int argc, VALUE *argv, VALUE ary)
{
struct cmp_opt_data cmp_opt = { 0, 0 };
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 (result == Qundef || 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(cmp_opt, Integer)) {
return ary_min_opt_fixnum(ary, 1, result);
}
else if (STRING_P(result) && CMP_OPTIMIZABLE(cmp_opt, String)) {
return ary_min_opt_string(ary, 1, result);
}
else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(cmp_opt, Float)) {
return ary_min_opt_float(ary, 1, result);
}
else {
return ary_min_generic(ary, 1, result);
}
}
}
if (result == Qundef) return Qnil;
return result;
}
|
#minmax ⇒ Array #minmax {|a, b| ... } ⇒ Array
Returns a new 2-element Array containing the minimum and maximum values from self
, either per method <=>
or per a given block:.
When no block is given, each element in self
must respond to method <=>
with an Integer; returns a new 2-element Array containing the minimum and maximum values from self
, per method <=>
:
[0, 1, 2].minmax # => [0, 2]
When a block is given, the block must return an Integer; the block is called self.size-1
times to compare elements; returns a new 2-element Array containing the minimum and maximum values from self
, per the block:
['0', '00', '000'].minmax {|a, b| a.size <=> b.size } # => ["0", "000"]
5907 5908 5909 5910 5911 5912 5913 5914 |
# File 'array.c', line 5907
static VALUE
rb_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));
}
|
#none? ⇒ Boolean #none? {|element| ... } ⇒ Boolean #none?(obj) ⇒ Boolean
Returns true
if no element of self
meet a given criterion.
With no block given and no argument, returns true
if self
has no truthy elements, false
otherwise:
[nil, false].none? # => true
[nil, 0, false].none? # => false
[].none? # => true
With a block given and no argument, calls the block with each element in self
; returns true
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
If argument obj
is given, returns true
if obj.===
no element, false
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
Related: Enumerable#none?
7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 |
# File 'array.c', line 7533
static VALUE
rb_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;
}
|
#one? ⇒ Boolean #one? {|element| ... } ⇒ Boolean #one?(obj) ⇒ Boolean
Returns true
if exactly one element of self
meets a given criterion.
With no block given and no argument, returns true
if self
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 and no argument, calls the block with each element in self
; returns true
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
If argument obj
is given, returns true
if obj.===
exactly one 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: Enumerable#one?
7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 |
# File 'array.c', line 7594
static VALUE
rb_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;
}
|
#permutation {|element| ... } ⇒ self #permutation(n) {|element| ... } ⇒ self #permutation ⇒ Object #permutation(n) ⇒ Object
When invoked with a block, yield all permutations of elements of self
; returns self
. The order of permutations is indeterminate.
When a block and an in-range positive Integer argument n
(0 < n <= self.size
) are given, calls the block with all n
-tuple permutations of self
.
Example:
a = [0, 1, 2]
a.permutation(2) {|permutation| p permutation }
Output:
[0, 1]
[0, 2]
[1, 0]
[1, 2]
[2, 0]
[2, 1]
Another example:
a = [0, 1, 2]
a.permutation(3) {|permutation| p permutation }
Output:
[0, 1, 2]
[0, 2, 1]
[1, 0, 2]
[1, 2, 0]
[2, 0, 1]
[2, 1, 0]
When n
is zero, calls the block once with a new empty Array:
a = [0, 1, 2]
a.permutation(0) {|permutation| p permutation }
Output:
[]
When n
is out of range (negative or larger than self.size
), does not call the block:
a = [0, 1, 2]
a.permutation(-1) {|permutation| fail 'Cannot happen' }
a.permutation(4) {|permutation| fail 'Cannot happen' }
When a block given but no argument, behaves the same as a.permutation(a.size)
:
a = [0, 1, 2]
a.permutation {|permutation| p permutation }
Output:
[0, 1, 2]
[0, 2, 1]
[1, 0, 2]
[1, 2, 0]
[2, 0, 1]
[2, 1, 0]
Returns a new Enumerator if no block given:
a = [0, 1, 2]
a.permutation # => #<Enumerator: [0, 1, 2]:permutation>
a.permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>
6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 |
# File 'array.c', line 6733
static VALUE
rb_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;
}
|
#pop ⇒ Object? #pop(n) ⇒ Object
Removes and returns trailing elements.
When no argument is given and self
is not empty, removes and returns the last element:
a = [:foo, 'bar', 2]
a.pop # => 2
a # => [:foo, "bar"]
Returns nil
if the array is empty.
When a non-negative Integer argument n
is given and is in range, removes and returns the last n
elements in a new Array:
a = [:foo, 'bar', 2]
a.pop(2) # => ["bar", 2]
If n
is positive and out of range, removes and returns all elements:
a = [:foo, 'bar', 2]
a.pop(50) # => [:foo, "bar", 2]
Related: #push, #shift, #unshift.
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 |
# File 'array.c', line 1396
static VALUE
rb_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;
}
|
#product(*other_arrays) ⇒ Object #product(*other_arrays) {|combination| ... } ⇒ self
Computes and returns or yields all combinations of elements from all the Arrays, including both self
and other_arrays
.
-
The number of combinations is the product of the sizes of all the arrays, including both
self
andother_arrays
. -
The order of the returned combinations is indeterminate.
When no block is given, returns the combinations as an Array of Arrays:
a = [0, 1, 2]
a1 = [3, 4]
a2 = [5, 6]
p = a.product(a1)
p.size # => 6 # a.size * a1.size
p # => [[0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4]]
p = a.product(a1, a2)
p.size # => 12 # a.size * a1.size * a2.size
p # => [[0, 3, 5], [0, 3, 6], [0, 4, 5], [0, 4, 6], [1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]
If any argument is an empty Array, returns an empty Array.
If no argument is given, returns an Array of 1-element Arrays, each containing an element of self
:
a.product # => [[0], [1], [2]]
When a block is given, yields each combination as an Array; returns self
:
a.product(a1) {|combination| p combination }
Output:
[0, 3]
[0, 4]
[1, 3]
[1, 4]
[2, 3]
[2, 4]
If any argument is an empty Array, does not call the block:
a.product(a1, a2, []) {|combination| fail 'Cannot happen' }
If no argument is given, yields each element of self
as a 1-element Array:
a.product {|combination| p combination }
Output:
[0]
[1]
[2]
7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 |
# File 'array.c', line 7184
static VALUE
rb_ary_product(int argc, VALUE *argv, VALUE ary)
{
int n = argc+1; /* How many arrays we're operating on */
volatile VALUE t0 = tmpary(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, FL_USER5);
rb_yield(subarray);
if (! FL_TEST(t0, FL_USER5)) {
rb_raise(rb_eRuntimeError, "product reentered");
}
else {
FL_UNSET(t0, FL_USER5);
}
}
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:
tmpary_discard(t0);
ALLOCV_END(t1);
return NIL_P(result) ? ary : result;
}
|
#push(*objects) ⇒ self Also known as: append
Appends trailing elements.
Appends each argument in objects
to self
; returns self
:
a = [:foo, 'bar', 2]
a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat]
Appends each argument as one element, even if it is another Array:
a = [:foo, 'bar', 2]
a1 = a.push([:baz, :bat], [:bam, :bad])
a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]
Array#append is an alias for Array#push.
Related: #pop, #shift, #unshift.
1343 1344 1345 1346 1347 |
# File 'array.c', line 1343
static VALUE
rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
{
return rb_ary_cat(ary, argv, argc);
}
|
#rassoc(obj) ⇒ nil
Returns the first element in self
that is an Array whose second element ==
obj
:
a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
a.rassoc(4) # => [2, 4]
Returns nil
if no such element is found.
Related: #assoc.
4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 |
# File 'array.c', line 4964
VALUE
rb_ary_rassoc(VALUE ary, VALUE value)
{
long i;
VALUE v;
for (i = 0; i < RARRAY_LEN(ary); ++i) {
v = 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;
}
|
#reject {|element| ... } ⇒ Object #reject ⇒ Object
Returns a new Array whose elements are all those from self
for which the block returns false
or nil
:
a = [:foo, 'bar', 2, 'bat']
a1 = a.reject {|element| element.to_s.start_with?('b') }
a1 # => [:foo, 2]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2]
a.reject # => #<Enumerator: [:foo, "bar", 2]:reject>
4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 |
# File 'array.c', line 4266
static VALUE
rb_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;
}
|
#reject! {|element| ... } ⇒ self? #reject! ⇒ Object
Removes each element for which the block returns a truthy value.
Returns self
if any elements removed:
a = [:foo, 'bar', 2, 'bat']
a.reject! {|element| element.to_s.start_with?('b') } # => [:foo, 2]
Returns nil
if no elements removed.
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2]
a.reject! # => #<Enumerator: [:foo, "bar", 2]:reject!>
4242 4243 4244 4245 4246 4247 4248 |
# File 'array.c', line 4242
static VALUE
rb_ary_reject_bang(VALUE ary)
{
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
return ary_reject_bang(ary);
}
|
#repeated_combination(n) {|combination| ... } ⇒ self #repeated_combination(n) ⇒ Object
Calls the block with each repeated combination of length n
of the elements of self
; each combination is an Array; returns self
. The order of the combinations is indeterminate.
When a block and a positive Integer argument n
are given, calls the block with each n
-tuple repeated combination of the elements of self
. The number of combinations is (n+1)(n+2)/2
.
n
= 1:
a = [0, 1, 2]
a.repeated_combination(1) {|combination| p combination }
Output:
[0]
[1]
[2]
n
= 2:
a.repeated_combination(2) {|combination| p combination }
Output:
[0, 0]
[0, 1]
[0, 2]
[1, 1]
[1, 2]
[2, 2]
If n
is zero, calls the block once with an empty Array.
If n
is negative, does not call the block:
a.repeated_combination(-1) {|combination| fail 'Cannot happen' }
Returns a new Enumerator if no block given:
a = [0, 1, 2]
a.repeated_combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
Using Enumerators, it’s convenient to show the combinations and counts for some values of n
:
e = a.repeated_combination(0)
e.size # => 1
e.to_a # => [[]]
e = a.repeated_combination(1)
e.size # => 3
e.to_a # => [[0], [1], [2]]
e = a.repeated_combination(2)
e.size # => 6
e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 |
# File 'array.c', line 7100
static VALUE
rb_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;
}
|
#repeated_permutation(n) {|permutation| ... } ⇒ self #repeated_permutation(n) ⇒ Object
Calls the block with each repeated permutation of length n
of the elements of self
; each permutation is an Array; returns self
. The order of the permutations is indeterminate.
When a block and a positive Integer argument n
are given, calls the block with each n
-tuple repeated permutation of the elements of self
. The number of permutations is self.size**n
.
n
= 1:
a = [0, 1, 2]
a.repeated_permutation(1) {|permutation| p permutation }
Output:
[0]
[1]
[2]
n
= 2:
a.repeated_permutation(2) {|permutation| p permutation }
Output:
[0, 0]
[0, 1]
[0, 2]
[1, 0]
[1, 1]
[1, 2]
[2, 0]
[2, 1]
[2, 2]
If n
is zero, calls the block once with an empty Array.
If n
is negative, does not call the block:
a.repeated_permutation(-1) {|permutation| fail 'Cannot happen' }
Returns a new Enumerator if no block given:
a = [0, 1, 2]
a.repeated_permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)>
Using Enumerators, it’s convenient to show the permutations and counts for some values of n
:
e = a.repeated_permutation(0)
e.size # => 1
e.to_a # => [[]]
e = a.repeated_permutation(1)
e.size # => 3
e.to_a # => [[0], [1], [2]]
e = a.repeated_permutation(2)
e.size # => 9
e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 |
# File 'array.c', line 6980
static VALUE
rb_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;
}
|
#replace(other_array) ⇒ self
Replaces the content of self
with the content of other_array
; returns self
:
a = [:foo, 'bar', 2]
a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3]
4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 |
# File 'array.c', line 4482
VALUE
rb_ary_replace(VALUE copy, VALUE orig)
{
rb_ary_modify_check(copy);
orig = to_ary(orig);
if (copy == orig) return copy;
if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
VALUE shared_root = 0;
if (ARY_OWNS_HEAP_P(copy)) {
ary_heap_free(copy);
}
else if (ARY_SHARED_P(copy)) {
shared_root = ARY_SHARED_ROOT(copy);
FL_UNSET_SHARED(copy);
}
FL_SET_EMBED(copy);
ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
if (shared_root) {
rb_ary_decrement_share(shared_root);
}
ARY_SET_LEN(copy, RARRAY_LEN(orig));
}
else {
VALUE shared_root = ary_make_shared(orig);
if (ARY_OWNS_HEAP_P(copy)) {
ary_heap_free(copy);
}
else {
rb_ary_unshare_safe(copy);
}
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);
}
ary_verify(copy);
return copy;
}
|
#reverse ⇒ Object
Returns a new Array with the elements of self
in reverse order.
a = ['foo', 'bar', 'two']
a1 = a.reverse
a1 # => ["two", "bar", "foo"]
3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 |
# File 'array.c', line 3038
static VALUE
rb_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_TRANSIENT(ary);
VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1;
do *p2-- = *p1++; while (--len > 0);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
return dup;
}
|
#reverse! ⇒ self
Reverses self
in place:
a = ['foo', 'bar', 'two']
a.reverse! # => ["two", "bar", "foo"]
3022 3023 3024 3025 3026 |
# File 'array.c', line 3022
static VALUE
rb_ary_reverse_bang(VALUE ary)
{
return rb_ary_reverse(ary);
}
|
#reverse_each {|element| ... } ⇒ self #reverse_each ⇒ Enumerator
Iterates backwards over array elements.
When a block given, passes, in reverse order, each element to the block; returns self
:
a = [:foo, 'bar', 2]
a.reverse_each {|element| puts "#{element.class} #{element}" }
Output:
Integer 2
String
Symbol foo
Allows the array to be modified during iteration:
a = [:foo, 'bar', 2]
a.reverse_each {|element| puts element; a.clear if element.to_s.start_with?('b') }
Output:
2
When no block given, returns a new Enumerator:
a = [:foo, 'bar', 2]
e = a.reverse_each
e # => #<Enumerator: [:foo, "bar", 2]:reverse_each>
a1 = e.each {|element| puts "#{element.class} #{element}" }
Output:
Integer 2
String
Symbol foo
Related: #each, #each_index.
2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 |
# File 'array.c', line 2617
static VALUE
rb_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;
}
|
#rindex(object) ⇒ Integer? #rindex {|element| ... } ⇒ Integer? #rindex ⇒ Object
Returns the index of the last element for which object == element
.
When argument object
is given but no block, returns the index of the last such element found:
a = [:foo, 'bar', 2, 'bar']
a.rindex('bar') # => 3
Returns nil
if no such object found.
When a block is given but no argument, 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
Returns nil
if the block never returns a truthy value.
When neither an argument nor a block is given, returns a new Enumerator:
a = [:foo, 'bar', 2, 'bar']
e = a.rindex
e # => #<Enumerator: [:foo, "bar", 2, "bar"]:rindex>
e.each {|element| element == 'bar' } # => 3
Related: #index.
2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 |
# File 'array.c', line 2099
static VALUE
rb_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;
}
|
#rotate ⇒ Object #rotate(count) ⇒ Object
Returns a new Array formed from self
with elements rotated from one end to the other.
When no argument given, returns a new Array that is like self
, except that the first element has been rotated to the last position:
a = [:foo, 'bar', 2, 'bar']
a1 = a.rotate
a1 # => ["bar", 2, "bar", :foo]
When given a non-negative Integer count
, returns a new Array with count
elements rotated from the beginning to the end:
a = [:foo, 'bar', 2]
a1 = a.rotate(2)
a1 # => [2, :foo, "bar"]
If count
is large, uses count % array.size
as the count:
a = [:foo, 'bar', 2]
a1 = a.rotate(20)
a1 # => [2, :foo, "bar"]
If count
is zero, returns a copy of self
, unmodified:
a = [:foo, 'bar', 2]
a1 = a.rotate(0)
a1 # => [:foo, "bar", 2]
When given a negative Integer count
, rotates in the opposite direction, from end to beginning:
a = [:foo, 'bar', 2]
a1 = a.rotate(-2)
a1 # => ["bar", 2, :foo]
If count
is small (far from zero), uses count % array.size
as the count:
a = [:foo, 'bar', 2]
a1 = a.rotate(-5)
a1 # => ["bar", 2, :foo]
3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 |
# File 'array.c', line 3182
static VALUE
rb_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_TRANSIENT(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;
}
|
#rotate! ⇒ self #rotate!(count) ⇒ self
Rotates self
in place by moving elements from one end to the other; returns self
.
When no argument given, rotates the first element to the last position:
a = [:foo, 'bar', 2, 'bar']
a.rotate! # => ["bar", 2, "bar", :foo]
When given a non-negative Integer count
, rotates count
elements from the beginning to the end:
a = [:foo, 'bar', 2]
a.rotate!(2)
a # => [2, :foo, "bar"]
If count
is large, uses count % array.size
as the count:
a = [:foo, 'bar', 2]
a.rotate!(20)
a # => [2, :foo, "bar"]
If count
is zero, returns self
unmodified:
a = [:foo, 'bar', 2]
a.rotate!(0)
a # => [:foo, "bar", 2]
When given a negative Integer count
, rotates in the opposite direction, from end to beginning:
a = [:foo, 'bar', 2]
a.rotate!(-2)
a # => ["bar", 2, :foo]
If count
is small (far from zero), uses count % array.size
as the count:
a = [:foo, 'bar', 2]
a.rotate!(-5)
a # => ["bar", 2, :foo]
3132 3133 3134 3135 3136 3137 3138 |
# File 'array.c', line 3132
static VALUE
rb_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;
}
|
#select {|element| ... } ⇒ Object #select ⇒ Object
Calls the block, if given, with each element of self
; returns a new Array containing those elements of self
for which the block returns a truthy value:
a = [:foo, 'bar', 2, :bam]
a1 = a.select {|element| element.to_s.start_with?('b') }
a1 # => ["bar", :bam]
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2, :bam]
a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select>
Array#filter is an alias for Array#select.
3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 |
# File 'array.c', line 3792
static VALUE
rb_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;
}
|
#select! {|element| ... } ⇒ self? #select! ⇒ Object
Calls the block, if given with each element of self
; removes from self
those elements for which the block returns false
or nil
.
Returns self
if any elements were removed:
a = [:foo, 'bar', 2, :bam]
a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
Returns nil
if no elements were removed.
Returns a new Enumerator if no block given:
a = [:foo, 'bar', 2, :bam]
a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!>
Array#filter! is an alias for Array#select!.
3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 |
# File 'array.c', line 3873
static VALUE
rb_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);
}
|
#shift ⇒ Object? #shift(n) ⇒ Object
Removes and returns leading elements.
When no argument is given, removes and returns the first element:
a = [:foo, 'bar', 2]
a.shift # => :foo
a # => ['bar', 2]
Returns nil
if self
is empty.
When positive Integer argument n
is given, removes the first n
elements; returns those elements in a new Array:
a = [:foo, 'bar', 2]
a.shift(2) # => [:foo, 'bar']
a # => [2]
If n
is as large as or larger than self.length
, removes all elements; returns those elements in a new Array:
a = [:foo, 'bar', 2]
a.shift(3) # => [:foo, 'bar', 2]
If n
is zero, returns a new empty Array; self
is unmodified.
Related: #push, #pop, #unshift.
1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 |
# File 'array.c', line 1476
static VALUE
rb_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;
}
|
#[](index) ⇒ Object? #[](start, length) ⇒ Object? #[](range) ⇒ Object? #[](aseq) ⇒ Object? #slice(index) ⇒ Object? #slice(start, length) ⇒ Object? #slice(range) ⇒ Object? #slice(aseq) ⇒ Object?
Returns elements from self
; does not modify self
.
When a single Integer argument index
is given, returns the element at offset index
:
a = [:foo, 'bar', 2]
a[0] # => :foo
a[2] # => 2
a # => [:foo, "bar", 2]
If index
is negative, counts relative to the end of self
:
a = [:foo, 'bar', 2]
a[-1] # => 2
a[-2] # => "bar"
If index
is out of range, returns nil
.
When two Integer arguments start
and length
are given, returns a new Array of size length
containing successive elements beginning at offset start
:
a = [:foo, 'bar', 2]
a[0, 2] # => [:foo, "bar"]
a[1, 2] # => ["bar", 2]
If start + length
is greater than self.length
, returns all elements from offset start
to the end:
a = [:foo, 'bar', 2]
a[0, 4] # => [:foo, "bar", 2]
a[1, 3] # => ["bar", 2]
a[2, 2] # => [2]
If start == self.size
and length >= 0
, returns a new empty Array.
If length
is negative, returns nil
.
When a single Range argument range
is given, treats range.min
as start
above and range.size
as length
above:
a = [:foo, 'bar', 2]
a[0..1] # => [:foo, "bar"]
a[1..2] # => ["bar", 2]
Special case: If range.start == a.size
, returns a new empty Array.
If range.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]
If range.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]
If range.start
is larger than the array size, returns nil
.
a = [:foo, 'bar', 2]
a[4..1] # => nil
a[4..0] # => nil
a[4..-1] # => nil
When a single Enumerator::ArithmeticSequence argument aseq
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, throws RangeError.
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 to Integer, and raises if it is impossible:
a = [:foo, 'bar', 2]
# Raises TypeError (no implicit conversion of Symbol into Integer):
a[:foo]
Array#slice is an alias for Array#[].
1801 1802 1803 1804 1805 1806 1807 1808 1809 |
# File 'array.c', line 1801
VALUE
rb_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]);
}
|
#slice!(n) ⇒ Object? #slice!(start, length) ⇒ nil #slice!(range) ⇒ nil
Removes and returns elements from self
.
When the only argument is an Integer n
, removes and returns the nth element in self
:
a = [:foo, 'bar', 2]
a.slice!(1) # => "bar"
a # => [:foo, 2]
If n
is negative, counts backwards from the end of self
:
a = [:foo, 'bar', 2]
a.slice!(-1) # => 2
a # => [:foo, "bar"]
If n
is out of range, returns nil
.
When the only arguments are Integers start
and length
, removes length
elements from self
beginning at offset start
; returns the deleted objects in a new Array:
a = [:foo, 'bar', 2]
a.slice!(0, 2) # => [:foo, "bar"]
a # => [2]
If start + length
exceeds the array size, removes and returns all elements from offset start
to the end:
a = [:foo, 'bar', 2]
a.slice!(1, 50) # => ["bar", 2]
a # => [:foo]
If start == a.size
and length
is non-negative, returns a new empty Array.
If length
is negative, returns nil
.
When the only argument is a Range object range
, treats range.min
as start
above and range.size
as length
above:
a = [:foo, 'bar', 2]
a.slice!(1..2) # => ["bar", 2]
a # => [:foo]
If range.start == a.size
, returns a new empty Array.
If range.start
is larger than the array size, returns nil
.
If range.end
is negative, counts backwards from the end of the array:
a = [:foo, 'bar', 2]
a.slice!(0..-2) # => [:foo, "bar"]
a # => [2]
If range.start
is negative, calculates the start index backwards from the end of the array:
a = [:foo, 'bar', 2]
a.slice!(-2..2) # => ["bar", 2]
a # => [:foo]
4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 |
# File 'array.c', line 4148
static VALUE
rb_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));
}
|
#sort ⇒ Object #sort {|a, b| ... } ⇒ Object
Returns a new Array whose elements are those from self
, sorted.
With no block, compares elements using operator <=>
(see Comparable):
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort
a1 # => ["a", "b", "c", "d", "e"]
With a block, calls the block with each element pair; for each element pair a
and b
, the block should return an integer:
-
Negative when
b
is to followa
. -
Zero when
a
andb
are equivalent. -
Positive when
a
is to followb
.
Example:
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort {|a, b| a <=> b }
a1 # => ["a", "b", "c", "d", "e"]
a2 = a.sort {|a, b| b <=> a }
a2 # => ["e", "d", "c", "b", "a"]
When the block returns zero, the order for a
and b
is indeterminate, and may be unstable:
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a1 = a.sort {|a, b| 0 }
a1 # => ["c", "e", "b", "d", "a"]
Related: Enumerable#sort_by.
3395 3396 3397 3398 3399 3400 3401 |
# File 'array.c', line 3395
VALUE
rb_ary_sort(VALUE ary)
{
ary = rb_ary_dup(ary);
rb_ary_sort_bang(ary);
return ary;
}
|
#sort! ⇒ self #sort! {|a, b| ... } ⇒ self
Returns self
with its elements sorted in place.
With no block, compares elements using operator <=>
(see Comparable):
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a.sort!
a # => ["a", "b", "c", "d", "e"]
With a block, calls the block with each element pair; for each element pair a
and b
, the block should return an integer:
-
Negative when
b
is to followa
. -
Zero when
a
andb
are equivalent. -
Positive when
a
is to followb
.
Example:
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a.sort! {|a, b| a <=> b }
a # => ["a", "b", "c", "d", "e"]
a.sort! {|a, b| b <=> a }
a # => ["e", "d", "c", "b", "a"]
When the block returns zero, the order for a
and b
is indeterminate, and may be unstable:
a = 'abcde'.split('').shuffle
a # => ["e", "b", "d", "a", "c"]
a.sort! {|a, b| 0 }
a # => ["d", "e", "c", "a", "b"]
3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 |
# File 'array.c', line 3297
VALUE
rb_ary_sort_bang(VALUE ary)
{
rb_ary_modify(ary);
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.cmp_opt.opt_methods = 0;
data.cmp_opt.opt_inited = 0;
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);
}
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 {
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_UNSET(tmp, FL_FREEZE);
FL_SET_EMBED(tmp);
ARY_SET_EMBED_LEN(tmp, 0);
FL_SET(tmp, FL_FREEZE);
}
/* tmp will be GC'ed. */
RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
}
ary_verify(ary);
return ary;
}
|
#sort_by! {|element| ... } ⇒ self #sort_by! ⇒ Object
Sorts the elements of self
in place, using an ordering determined by the block; returns self.
Calls the block with each successive element; sorts elements based on the values returned from the block.
For duplicates returned by the block, the ordering is indeterminate, and may be unstable.
This example sorts strings based on their sizes:
a = ['aaaa', 'bbb', 'cc', 'd']
a.sort_by! {|element| element.size }
a # => ["d", "cc", "bbb", "aaaa"]
Returns a new Enumerator if no block given:
a = ['aaaa', 'bbb', 'cc', 'd']
a.sort_by! # => #<Enumerator: ["aaaa", "bbb", "cc", "d"]:sort_by!>
3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 |
# File 'array.c', line 3594
static VALUE
rb_ary_sort_by_bang(VALUE ary)
{
VALUE sorted;
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_modify(ary);
sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);
rb_ary_replace(ary, sorted);
return ary;
}
|
#sum(init = 0) ⇒ Object #sum(init = 0) {|element| ... } ⇒ Object
When no block is given, returns the object equivalent to:
sum = init
array.each {|element| sum += element }
sum
For example, <tt>[e1, e2, e3].sum</tt> returns </tt>init + e1 + e2 + e3</tt>.
Examples:
a = [0, 1, 2, 3]
a.sum # => 6
a.sum(100) # => 106
The elements need not be numeric, but must be <tt>+</tt>-compatible
with each other and with +init+:
a = ['abc', 'def', 'ghi']
a.sum('jkl') # => "jklabcdefghi"
When a block is given, it is called with each element
and the block's return value (instead of the element itself) is used as the addend:
a = ['zero', 1, :two]
s = a.sum('Coerced and concatenated: ') {|element| element.to_s }
s # => "Coerced and concatenated: zero1two"
Notes:
- Array#join and Array#flatten may be faster than Array#sum
for an \Array of Strings or an \Array of Arrays.
- Array#sum method may not respect method redefinition of "+" methods such as Integer#+.
7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 |
# File 'array.c', line 7706
static VALUE
rb_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;
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_TYPE_P(e, T_BIGNUM))
v = rb_big_plus(e, v);
else if (RB_TYPE_P(e, T_RATIONAL)) {
if (r == Qundef)
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_TYPE_P(e, T_BIGNUM))
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;
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;
}
|
#take(n) ⇒ Object
Returns a new Array containing the first n
element of self
, where n
is a non-negative Integer; does not modify self
.
Examples:
a = [0, 1, 2, 3, 4, 5]
a.take(1) # => [0]
a.take(2) # => [0, 1]
a.take(50) # => [0, 1, 2, 3, 4, 5]
a # => [0, 1, 2, 3, 4, 5]
7288 7289 7290 7291 7292 7293 7294 7295 7296 |
# File 'array.c', line 7288
static VALUE
rb_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);
}
|
#take_while {|element| ... } ⇒ Object #take_while ⇒ Object
Returns a new Array containing zero or more leading elements of self
; does not modify self
.
With a block given, calls the block with each successive element of self
; stops if the block returns false
or nil
; 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 # => [0, 1, 2, 3, 4, 5]
With no block given, returns a new Enumerator:
[0, 1].take_while # => #<Enumerator: [0, 1]:take_while>
7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 |
# File 'array.c', line 7318
static VALUE
rb_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));
}
|
#to_a ⇒ self
When self
is an instance of Array, returns self
:
a = [:foo, 'bar', 2]
a.to_a # => [:foo, "bar", 2]
Otherwise, returns a new Array containing the elements of self
:
class MyArray < Array; end
a = MyArray.new(['foo', 'bar', 'two'])
a.instance_of?(Array) # => false
a.kind_of?(Array) # => true
a1 = a.to_a
a1 # => ["foo", "bar", "two"]
a1.class # => Array # Not MyArray
2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 |
# File 'array.c', line 2917
static VALUE
rb_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;
}
|
#to_ary ⇒ self
Returns self
.
2981 2982 2983 2984 2985 |
# File 'array.c', line 2981
static VALUE
rb_ary_to_ary_m(VALUE ary)
{
return ary;
}
|
#to_h ⇒ Object #to_h {|item| ... } ⇒ Object
Returns a new Hash formed from self
.
When a block is given, calls the block with each array element; the block must return a 2-element Array whose two elements form a key-value pair in the returned Hash:
a = ['foo', :bar, 1, [2, 3], {baz: 4}]
h = a.to_h {|item| [item, item] }
h # => {"foo"=>"foo", :bar=>:bar, 1=>1, [2, 3]=>[2, 3], {:baz=>4}=>{:baz=>4}}
When no block is given, self
must be an Array of 2-element sub-arrays, each sub-array is formed into a key-value pair in the new Hash:
[].to_h # => {}
a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']]
h = a.to_h
h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"}
2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 |
# File 'array.c', line 2950
static VALUE
rb_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;
}
|
#transpose ⇒ Object
Transposes the rows and columns in an Array of Arrays; the nested Arrays must all be the same size:
a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 |
# File 'array.c', line 4445
static VALUE
rb_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;
}
|
#union(*other_arrays) ⇒ Object
Returns a new Array that is the union of self
and all given Arrays other_arrays
; duplicates are removed; order is preserved; items are compared using eql?
:
[0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3]
[0, 1, 2, 3].union([3, 2], [1, 0]) # => [0, 1, 2, 3]
Returns a copy of self
if no arguments given.
Related: Array#|.
5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 |
# File 'array.c', line 5530
static VALUE
rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
{
int i;
long sum;
VALUE hash, ary_union;
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) {
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]);
ary_union = rb_hash_values(hash);
ary_recycle_hash(hash);
return ary_union;
}
|
#uniq ⇒ Object #uniq {|element| ... } ⇒ Object
Returns a new Array containing those elements from self
that are not duplicates, the first occurrence always being retained.
With no block given, identifies and omits duplicates using method eql?
to compare.
a = [0, 0, 1, 1, 2, 2]
a.uniq # => [0, 1, 2]
With a block given, calls the block for each element; identifies (using method eql?
) and omits duplicate values, that is, those elements for which the block returns the same value:
a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 |
# File 'array.c', line 6001
static VALUE
rb_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);
}
if (hash) {
ary_recycle_hash(hash);
}
return uniq;
}
|
#uniq! ⇒ self? #uniq! {|element| ... } ⇒ self?
Removes duplicate elements from self
, the first occurrence always being retained; returns self
if any elements removed, nil
otherwise.
With no block given, identifies and removes elements using method eql?
to compare.
Returns self
if any elements removed:
a = [0, 0, 1, 1, 2, 2]
a.uniq! # => [0, 1, 2]
Returns nil
if no elements removed.
With a block given, calls the block for each element; identifies (using method eql?
) and removes elements for which the block returns duplicate values.
Returns self
if any elements removed:
a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq! {|element| element.size } # => ['a', 'aa', 'aaa']
Returns nil
if no elements removed.
5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 |
# File 'array.c', line 5950
static VALUE
rb_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) && !ARY_EMBED_P(ary)) {
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
}
ary_resize_capa(ary, hash_size);
rb_hash_foreach(hash, push_value, ary);
ary_recycle_hash(hash);
return ary;
}
|
#unshift(*objects) ⇒ self Also known as: prepend
Prepends the given objects
to self
:
a = [:foo, 'bar', 2]
a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]
Array#prepend is an alias for Array#unshift.
Related: #push, #pop, #shift.
1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 |
# File 'array.c', line 1636
static VALUE
rb_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;
}
|
#values_at(*indexes) ⇒ Object
Returns a new Array whose elements are the elements of self
at the given Integer indexes
.
For each positive index
, returns the element at offset index
:
a = [:foo, 'bar', 2]
a.values_at(0, 2) # => [:foo, 2]
The given indexes
may be in any order, and may repeat:
a = [:foo, 'bar', 2]
a.values_at(2, 0, 1, 0, 2) # => [2, :foo, "bar", :foo, 2]
Assigns nil
for an index
that is too large:
a = [:foo, 'bar', 2]
a.values_at(0, 3, 1, 3) # => [:foo, nil, "bar", nil]
Returns a new empty Array if no arguments given.
For each negative index
, counts backward from the end of the array:
a = [:foo, 'bar', 2]
a.values_at(-1, -3) # => [2, :foo]
Assigns nil
for an index
that is too small:
a = [:foo, 'bar', 2]
a.values_at(0, -5, 1, -6, 2) # => [:foo, nil, "bar", nil, 2]
The given indexes
may have a mixture of signs:
a = [:foo, 'bar', 2]
a.values_at(0, -2, 1, -1) # => [:foo, "bar", "bar", 2]
3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 |
# File 'array.c', line 3760
static VALUE
rb_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;
}
|
#zip(*other_arrays) ⇒ Object #zip(*other_arrays) {|other_array| ... } ⇒ nil
When no block given, returns a new Array new_array
of size self.size
whose elements are Arrays.
Each nested array new_array[n]
is of size other_arrays.size+1
, and contains:
-
The nth element of
self
. -
The nth element of each of the
other_arrays
.
If all other_arrays
and self
are the same size:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
If any array in other_arrays
is smaller than self
, fills to self.size
with nil
:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2]
c = [:c0, :c1]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]]
If any array in other_arrays
is larger than self
, its trailing elements are ignored:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3, :b4]
c = [:c0, :c1, :c2, :c3, :c4, :c5]
d = a.zip(b, c)
d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
When a block is given, calls the block with each of the sub-arrays (formed as above); returns nil
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
a.zip(b, c) {|sub_array| p sub_array} # => nil
Output:
[:a0, :b0, :c0]
[:a1, :b1, :c1]
[:a2, :b2, :c2]
[:a3, :b3, :c3]
4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 |
# File 'array.c', line 4377
static VALUE
rb_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;
}
|
#|(other_array) ⇒ Object
Returns the union of array
and Array other_array
; duplicates are removed; order is preserved; items are compared using eql?
:
[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: Array#union.
5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 |
# File 'array.c', line 5494
static VALUE
rb_ary_or(VALUE ary1, VALUE ary2)
{
VALUE hash, ary3;
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
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);
ary3 = rb_hash_values(hash);
ary_recycle_hash(hash);
return ary3;
}
|