Class: Array
Overview
An Array object is an ordered, integer-indexed collection of objects, called elements; the object represents an array data structure.
An element may be any object (even another array); elements may be any mixture of objects of different types.
Important data structures that use arrays include:
There are also array-like data structures:
-
Associative array (see Hash).
-
Directory (see Dir).
-
Environment (see ENV).
-
Set (see Set).
-
String (see String).
Array Indexes
Array indexing starts at 0, as in C or Java.
A non-negative 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.
-
…
In-Range and Out-of-Range Indexes
A non-negative index is in range if and only 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 and only 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.
Effective Index
Although the effective index into an array is always an integer, some methods (both within class Array and elsewhere) accept one or more non-integer arguments that are integer-convertible objects.
Creating Arrays
You can create an Array object explicitly with:
-
An array literal:
[1, 'one', :one, [2, 'two', :two]]
-
A %w or %W string-array Literal:
%w[foo bar baz] # => ["foo", "bar", "baz"] %w[1 % *] # => ["1", "%", "*"]
-
A %i or %I symbol-array Literal:
%i[foo bar baz] # => [:foo, :bar, :baz] %i[1 % *] # => [:"1", :%, :*]
-
Method Kernel#Array:
Array(["a", "b"]) # => ["a", "b"] Array(1..5) # => [1, 2, 3, 4, 5] Array(key: :value) # => [[:key, :value]] Array(nil) # => [] Array(1) # => [1] Array({:a => "a", :b => "b"}) # => [[:a, "a"], [:b, "b"]]
-
Method Array.new:
Array.new # => [] Array.new(3) # => [nil, nil, nil] Array.new(4) {Hash.new} # => [{}, {}, {}, {}] Array.new(3, true) # => [true, true, true]
Note that the last example above populates the array with references to the same object. This is recommended only in cases where that object is a natively immutable object such as a symbol, a numeric,
nil
,true
, orfalse
.Another way to create an array with various objects, using a block; this usage is safe for mutable objects such as hashes, strings or other arrays:
Array.new(4) {|i| i.to_s } # => ["0", "1", "2", "3"]
Here is a way to create a multi-dimensional array:
Array.new(3) {Array.new(3)} # => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]
A number of Ruby methods, both in the core and in the standard library, provide instance method to_a
, which converts an object to an array.
-
ARGF#to_a
-
Array#to_a
-
Enumerable#to_a
-
Hash#to_a
-
MatchData#to_a
-
NilClass#to_a
-
OptionParser#to_a
-
Range#to_a
-
Set#to_a
-
Struct#to_a
-
Time#to_a
-
Benchmark::Tms#to_a
-
CSV::Table#to_a
-
Enumerator::Lazy#to_a
-
Gem::List#to_a
-
Gem::NameTuple#to_a
-
Gem::Platform#to_a
-
Gem::RequestSet::Lockfile::Tokenizer#to_a
-
Gem::SourceList#to_a
-
OpenSSL::X509::Extension#to_a
-
OpenSSL::X509::Name#to_a
-
Racc::ISet#to_a
-
Rinda::RingFinger#to_a
-
Ripper::Lexer::Elem#to_a
-
RubyVM::InstructionSequence#to_a
-
YAML::DBM#to_a
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]
What’s Here
First, what’s elsewhere. Class Array
:
-
Inherits from class Object.
-
Includes module Enumerable, which provides dozens of additional methods.
Here, class Array
provides methods that are useful for:
Methods for Creating an Array
-
::[]: Returns a new array populated with given objects.
-
::new: Returns a new array.
-
::try_convert: Returns a new array created from a given object.
See also Creating Arrays.
Methods for Querying
-
#all?: Returns whether all elements meet a given criterion.
-
#any?: Returns whether any element meets a given criterion.
-
#count: Returns the count of elements that meet a given criterion.
-
#empty?: Returns whether there are no elements.
-
#find_index (aliased as #index): Returns the index of the first element that meets a given criterion.
-
#hash: Returns the integer hash code.
-
#include?: Returns whether any element
==
a given object. -
#length (aliased as #size): Returns the count of elements.
-
#none?: Returns whether no element
==
a given object. -
#one?: Returns whether exactly one element
==
a given object. -
#rindex: Returns the index of the last element that meets a given criterion.
Methods for Comparing
-
#<=>: Returns -1, 0, or 1, as
self
is less than, equal to, or greater than a given object. -
#==: Returns whether each element in
self
is==
to the corresponding element in a given object. -
#eql?: Returns whether each element in
self
iseql?
to the corresponding element in a given object.
Methods for Fetching
These methods do not modify self
.
-
#[] (aliased as #slice): Returns consecutive elements as determined by a given argument.
-
#assoc: Returns the first element that is an array whose first element
==
a given object. -
#at: Returns the element at a given offset.
-
#bsearch: Returns an element selected via a binary search as determined by a given block.
-
#bsearch_index: Returns the index of an element selected via a binary search as determined by a given block.
-
#compact: Returns an array containing all non-
nil
elements. -
#dig: Returns the object in nested objects that is specified by a given index and additional arguments.
-
#drop: Returns trailing elements as determined by a given index.
-
#drop_while: Returns trailing elements as determined by a given block.
-
#fetch: Returns the element at a given offset.
-
#fetch_values: Returns elements at given offsets.
-
#first: Returns one or more leading elements.
-
#last: Returns one or more trailing elements.
-
#max: Returns one or more maximum-valued elements, as determined by
#<=>
or a given block. -
#min: Returns one or more minimum-valued elements, as determined by
#<=>
or a given block. -
#minmax: Returns the minimum-valued and maximum-valued elements, as determined by
#<=>
or a given block. -
#rassoc: Returns the first element that is an array whose second element
==
a given object. -
#reject: Returns an array containing elements not rejected by a given block.
-
#reverse: Returns all elements in reverse order.
-
#rotate: Returns all elements with some rotated from one end to the other.
-
#sample: Returns one or more random elements.
-
#select (aliased as #filter): Returns an array containing elements selected by a given block.
-
#shuffle: Returns elements in a random order.
-
#sort: Returns all elements in an order determined by
#<=>
or a given block. -
#take: Returns leading elements as determined by a given index.
-
#take_while: Returns leading elements as determined by a given block.
-
#uniq: Returns an array containing non-duplicate elements.
-
#values_at: Returns the elements at given offsets.
Methods for Assigning
These methods add, replace, or reorder elements in self
.
-
#<<: Appends an element.
-
#[]=: Assigns specified elements with a given object.
-
#concat: Appends all elements from given arrays.
-
#fill: Replaces specified elements with specified objects.
-
#flatten!: Replaces each nested array in
self
with the elements from that array. -
#initialize_copy (aliased as #replace): Replaces the content of
self
with the content of a given array. -
#insert: Inserts given objects at a given offset; does not replace elements.
-
#push (aliased as #append): Appends elements.
-
#reverse!: Replaces
self
with its elements reversed. -
#rotate!: Replaces
self
with its elements rotated. -
#shuffle!: Replaces
self
with its elements in random order. -
#sort!: Replaces
self
with its elements sorted, as determined by#<=>
or a given block. -
#sort_by!: Replaces
self
with its elements sorted, as determined by a given block. -
#unshift (aliased as #prepend): Prepends leading elements.
Methods for Deleting
Each of these methods removes elements from self
:
-
#clear: Removes all elements.
-
#compact!: Removes all
nil
elements. -
#delete: Removes elements equal to a given object.
-
#delete_at: Removes the element at a given offset.
-
#delete_if: Removes elements specified by a given block.
-
#keep_if: Removes elements not specified by a given block.
-
#pop: Removes and returns the last element.
-
#reject!: Removes elements specified by a given block.
-
#select! (aliased as #filter!): Removes elements not specified by a given block.
-
#shift: Removes and returns the first element.
-
#slice!: Removes and returns a sequence of elements.
-
#uniq!: Removes duplicates.
Methods for Combining
-
#&: Returns an array containing elements found both in
self
and a given array. -
#+: Returns an array containing all elements of
self
followed by all elements of a given array. -
#-: Returns an array containing all elements of
self
that are not found in a given array. -
#|: Returns an array containing all element of
self
and all elements of a given array, duplicates removed. -
#difference: Returns an array containing all elements of
self
that are not found in any of the given arrays.. -
#intersection: Returns an array containing elements found both in
self
and in each given array. -
#product: Returns or yields all combinations of elements from
self
and given arrays. -
#reverse: Returns an array containing all elements of
self
in reverse order. -
#union: Returns an array containing all elements of
self
and all elements of given arrays, duplicates removed.
Methods for Iterating
-
#combination: Calls a given block with combinations of elements of
self
; a combination does not use the same element more than once. -
#cycle: Calls a given block with each element, then does so again, for a specified number of times, or forever.
-
#each: Passes each element to a given block.
-
#each_index: Passes each element index to a given block.
-
#permutation: Calls a given block with permutations of elements of
self
; a permutation does not use the same element more than once. -
#repeated_combination: Calls a given block with combinations of elements of
self
; a combination may use the same element more than once. -
#repeated_permutation: Calls a given block with permutations of elements of
self
; a permutation may use the same element more than once. -
#reverse_each: Passes each element, in reverse order, to a given block.
Methods for Converting
-
#collect (aliased as #map): Returns an array containing the block return-value for each element.
-
#collect! (aliased as #map!): Replaces each element with a block return-value.
-
#flatten: Returns an array that is a recursive flattening of
self
. -
#inspect (aliased as #to_s): Returns a new String containing the elements.
-
#join: Returns a newsString containing the elements joined by the field separator.
-
#to_a: Returns
self
or a new array containing all elements. -
#to_ary: Returns
self
. -
#to_h: Returns a new hash formed from the elements.
-
#transpose: Transposes
self
, which must be an array of arrays. -
#zip: Returns a new array of arrays containing
self
and given arrays.
Other Methods
-
#*: Returns one of the following:
-
With integer argument
n
, a new array that is the concatenation ofn
copies ofself
. -
With string argument
field_separator
, a new string that is equivalent tojoin(field_separator)
.
-
-
#pack: Packs the elements into a binary sequence.
-
#sum: Returns a sum of elements according to either
+
or a given block.
Class Method Summary collapse
-
.[](*args) ⇒ Object
Returns a new array, populated with the given objects:.
-
.new(*args) ⇒ Object
:nodoc:.
-
.try_convert(object) ⇒ Object?
Attempts to return an array, based on the given
object
.
Instance Method Summary collapse
-
#&(other_array) ⇒ Object
Returns a new array containing the intersection of
self
andother_array
; that is, containing those elements found in bothself
andother_array
:. -
#*(times) ⇒ Object
When non-negative integer argument
n
is given, returns a new array built by concatenatingn
copies ofself
:. -
#+(other_array) ⇒ Object
Returns a new array containing all elements of
self
followed by all elements ofother_array
:. -
#-(other_array) ⇒ Object
Returns a new array containing only those elements of
self
that are not found inother_array
; the order fromself
is preserved:. -
#<<(object) ⇒ self
Appends
object
as the last element inself
; returnsself
:. -
#<=>(other_array) ⇒ -1, ...
Returns -1, 0, or 1 as
self
is determined to be less than, equal to, or greater thanother_array
. -
#==(other_array) ⇒ Boolean
Returns whether both:.
-
#[](*args) ⇒ Object
Returns elements from
self
; does not modifyself
. -
#[]=(*args) ⇒ Object
Assigns elements in
self
, based on the givenobject
; returnsobject
. -
#all?(*args) ⇒ Object
Returns whether for every element of
self
, a given criterion is satisfied. -
#any?(*args) ⇒ Object
Returns whether for any element of
self
, a given criterion is satisfied. -
#assoc(object) ⇒ nil
Returns the first element
ele
inself
such thatele
is an array andele[0] == object
:. -
#at(index) ⇒ Object?
Returns the element of
self
specified by the givenindex
ornil
if there is no such element;index
must be an integer-convertible object. -
#bsearch ⇒ Object
Returns the element from
self
found by a binary search, ornil
if the search found no suitable element. -
#bsearch_index ⇒ Object
Returns the integer index of the element from
self
found by a binary search, ornil
if the search found no suitable element. -
#clear ⇒ self
Removes all elements from
self
; returnsself
:. -
#collect ⇒ Object
With a block given, calls the block with each element of
self
; returns a new array whose elements are the return values from the block:. -
#collect! ⇒ Object
With a block given, calls the block with each element of
self
and replaces the element with the block’s return value; returnsself
:. -
#combination(num) ⇒ Object
When a block and a positive integer-convertible object argument
count
(0 < count <= self.size
) are given, calls the block with each combination ofself
of sizecount
; returnsself
:. -
#compact ⇒ Object
Returns a new array containing only the non-
nil
elements fromself
; element order is preserved:. -
#compact! ⇒ self?
Removes all
nil
elements fromself
; Returnsself
if any elements are removed,nil
otherwise:. -
#concat(*other_arrays) ⇒ self
Adds to
self
all elements from each array inother_arrays
; returnsself
:. -
#count(*args) ⇒ Object
Returns a count of specified elements.
-
#cycle(*args) ⇒ Object
With a block given, may call the block, depending on the value of argument
count
;count
must be an integer-convertible object, ornil
. -
#deconstruct ⇒ Object
:nodoc:.
-
#delete(item) ⇒ Object
Removes zero or more elements from
self
. -
#delete_at(index) ⇒ nil
Removes the element of
self
at the givenindex
, which must be an integer-convertible object. -
#delete_if ⇒ Object
With a block given, calls the block with each element of
self
; removes the element if the block returns a truthy value; returnsself
:. -
#difference(*other_arrays = []) ⇒ Object
Returns a new array containing only those elements from
self
that are not found in any of the givenother_arrays
; items are compared usingeql?
; order fromself
is preserved:. -
#dig(index, *identifiers) ⇒ Object
Finds and returns the object in nested object specified by
index
andidentifiers
; the nested objects may be instances of various classes. -
#drop(count) ⇒ Object
Returns a new array containing all but the first
count
element ofself
, wherecount
is a non-negative integer; does not modifyself
. -
#drop_while ⇒ Object
With a block given, calls the block with each successive element of
self
; stops if the block returnsfalse
ornil
; returns a new array omitting those elements for which the block returned a truthy value; does not modifyself
:. -
#each ⇒ Object
With a block given, iterates over the elements of
self
, passing each element to the block; returnsself
:. -
#each_index ⇒ Object
With a block given, iterates over the elements of
self
, passing each array index to the block; returnsself
:. -
#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])
:. -
#fetch(*args) ⇒ Object
Returns the element of
self
at offsetindex
ifindex
is in range;index
must be an integer-convertible object. -
#fill(*args) ⇒ Object
Replaces selected elements in
self
; may add elements toself
; always returnsself
(never a new array). -
#filter ⇒ Object
With a block given, calls the block with each element of
self
; returns a new array containing those elements ofself
for which the block returns a truthy value:. -
#filter! ⇒ Object
With a block given, calls the block with each element of
self
; removes fromself
those elements for which the block returnsfalse
ornil
. -
#find_index(*args) ⇒ Object
Returns the zero-based integer index of a specified element, or
nil
. -
#flatten(depth = nil) ⇒ Object
Returns a new array that is a recursive flattening of
self
todepth
levels of recursion;depth
must be an integer-convertible object ornil
. -
#flatten!(depth = nil) ⇒ self?
Returns
self
as a recursively flattening ofself
todepth
levels of recursion;depth
must be an integer-convertible object, ornil
. -
#freeze ⇒ self
Freezes
self
(if not already frozen); returnsself
:. -
#hash ⇒ Integer
Returns the integer hash value for
self
. -
#include?(object) ⇒ Boolean
Returns whether for some element
element
inself
,object == element
:. -
#index(*args) ⇒ Object
Returns the zero-based integer index of a specified element, or
nil
. -
#initialize(*args) ⇒ Object
constructor
Returns a new array.
-
#initialize_copy(orig) ⇒ Object
Replaces the elements of
self
with the elements ofother_array
, which must be an array-convertible object; returnsself
:. -
#insert(index, *objects) ⇒ self
Inserts the given
objects
as elements ofself
; returnsself
. -
#inspect ⇒ Object
(also: #to_s)
Returns the new string formed by calling method
#inspect
on each array element:. -
#intersect?(other_array) ⇒ Boolean
Returns whether
other_array
has at least one element that is#eql?
to some element ofself
:. -
#intersection(*other_arrays) ⇒ Object
Returns a new array containing each element in
self
that is#eql?
to at least one element in each of the givenother_arrays
; duplicates are omitted:. -
#join(separator = $,) ⇒ Object
Returns the new string formed by joining the converted elements of
self
; for each elementelement
:. -
#keep_if ⇒ Object
With a block given, calls the block with each element of
self
; removes the element fromself
if the block does not return a truthy value:. -
#length ⇒ Object
Returns the count of elements in
self
:. -
#map ⇒ Object
With a block given, calls the block with each element of
self
; returns a new array whose elements are the return values from the block:. -
#map! ⇒ Object
With a block given, calls the block with each element of
self
and replaces the element with the block’s return value; returnsself
:. -
#max(*args) ⇒ Object
Returns one of the following:.
-
#min(*args) ⇒ Object
Returns one of the following:.
-
#minmax ⇒ Object
Returns a 2-element array containing the minimum-valued and maximum-valued elements from
self
; does not modifyself
. -
#none?(*args) ⇒ Object
Returns
true
if no element ofself
meets a given criterion,false
otherwise. -
#one?(*args) ⇒ Object
Returns
true
if exactly one element ofself
meets a given criterion. -
#permutation(*args) ⇒ Object
Iterates over permutations of the elements of
self
; the order of permutations is indeterminate. -
#pop(*args) ⇒ Object
Removes and returns trailing elements of
self
. -
#product(*args) ⇒ Object
Computes all combinations of elements from all the arrays, including both
self
andother_arrays
:. -
#push(*args) ⇒ Object
(also: #append)
Appends each argument in
objects
toself
; returnsself
:. -
#rassoc(object) ⇒ nil
Returns the first element
ele
inself
such thatele
is an array andele[1] == object
:. -
#reject ⇒ Object
With a block given, returns a new array whose elements are all those from
self
for which the block returnsfalse
ornil
:. -
#reject! ⇒ Object
With a block given, calls the block with each element of
self
; removes each element for which the block returns a truthy value. -
#repeated_combination(num) ⇒ Object
With a block given, calls the block with each repeated combination of length
size
of the elements ofself
; each combination is an array; returnsself
. -
#repeated_permutation(num) ⇒ Object
With a block given, calls the block with each repeated permutation of length
size
of the elements ofself
; each permutation is an array; returnsself
. -
#replace(orig) ⇒ Object
Replaces the elements of
self
with the elements ofother_array
, which must be an array-convertible object; returnsself
:. -
#reverse ⇒ Object
Returns a new array containing the elements of
self
in reverse order:. -
#reverse! ⇒ self
Reverses the order of the elements of
self
; returnsself
:. -
#reverse_each ⇒ Object
When a block given, iterates backwards over the elements of
self
, passing, in reverse order, each element to the block; returnsself
:. -
#rindex(*args) ⇒ Object
Returns the index of the last element for which
object == element
. -
#rotate(count = 1) ⇒ Object
Returns a new array formed from
self
with elements rotated from one end to the other. -
#rotate!(count = 1) ⇒ self
Rotates
self
in place by moving elements from one end to the other; returnsself
. -
#select ⇒ Object
With a block given, calls the block with each element of
self
; returns a new array containing those elements ofself
for which the block returns a truthy value:. -
#select! ⇒ Object
With a block given, calls the block with each element of
self
; removes fromself
those elements for which the block returnsfalse
ornil
. -
#shift(*args) ⇒ Object
Removes and returns leading elements from
self
. -
#size ⇒ Object
Returns the count of elements in
self
:. -
#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 containing the elements of
self
, sorted. -
#sort! ⇒ Object
Like Array#sort, but returns
self
with its elements sorted in place. -
#sort_by! ⇒ Object
With a block given, sorts the elements of
self
in place; returns self. -
#sum(*args) ⇒ Object
With no block given, returns the sum of
init
and all elements ofself
; for arrayarray
and valueinit
, equivalent to:. -
#take(count) ⇒ Object
Returns a new array containing the first
count
element ofself
(as available);count
must be a non-negative numeric; does not modifyself
:. -
#take_while ⇒ Object
With a block given, calls the block with each successive element of
self
; stops iterating if the block returnsfalse
ornil
; returns a new array containing those elements for which the block returned a truthy value:. -
#to_a ⇒ self
When
self
is an instance ofArray
, returnsself
. -
#to_ary ⇒ self
Returns
self
. -
#to_h ⇒ Object
Returns a new hash formed from
self
. -
#transpose ⇒ Object
Returns a new array that is
self
as a transposed matrix:. -
#union(*other_arrays) ⇒ Object
Returns a new array that is the union of the elements of
self
and all given arraysother_arrays
; items are compared usingeql?
:. -
#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(*args) ⇒ Object
(also: #prepend)
Prepends the given
objects
toself
:. -
#values_at(*specifiers) ⇒ Object
Returns elements from
self
in a new array; does not modifyself
. -
#zip(*args) ⇒ Object
With no block given, combines
self
with the collection ofother_arrays
; returns a new array of sub-arrays:. -
#|(other_array) ⇒ Object
Returns the union of
self
andother_array
; duplicates are removed; order is preserved; items are compared usingeql?
:.
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, #first, #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, default_value = nil) ⇒ Object #new(size = 0) {|index| ... } ⇒ Object
Returns a new array.
With no block and no argument given, returns a new empty array:
Array.new # => []
With no block and array argument given, returns a new array with the same elements:
Array.new([:foo, 'bar', 2]) # => [:foo, "bar", 2]
With no block and integer argument given, returns a new array containing that many instances of the given default_value
:
Array.new(0) # => []
Array.new(3) # => [nil, nil, nil]
Array.new(2, 3) # => [3, 3]
With a block given, returns an array of the given size
; calls the block with each index
in the range (0...size)
; the element at that index
in the returned array is the blocks return value:
Array.new(3) {|index| "Element #{index}" } # => ["Element 0", "Element 1", "Element 2"]
A common pitfall for new Rubyists is providing an expression as default_value
:
array = Array.new(2, {})
array # => [{}, {}]
array[0][:a] = 1
array # => [{a: 1}, {a: 1}], as array[0] and array[1] are same object
If you want the elements of the array to be distinct, you should pass a block:
array = Array.new(2) { {} }
array # => [{}, {}]
array[0][:a] = 1
array # => [{a: 1}, {}], as array[0] and array[1] are different objects
Raises TypeError if the first argument is not either an array or an integer-convertible object). Raises ArgumentError if the first argument is a negative integer.
Related: see Methods for Creating an Array.
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 |
# File 'array.c', line 1124
static VALUE
rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
{
long len;
VALUE size, val;
rb_ary_modify(ary);
if (argc == 0) {
rb_ary_reset(ary);
RUBY_ASSERT(ARY_EMBED_P(ary));
RUBY_ASSERT(ARY_EMBED_LEN(ary) == 0);
if (rb_block_given_p()) {
rb_warning("given block not used");
}
return ary;
}
rb_scan_args(argc, argv, "02", &size, &val);
if (argc == 1 && !FIXNUM_P(size)) {
val = rb_check_array_type(size);
if (!NIL_P(val)) {
rb_ary_replace(ary, val);
return ary;
}
}
len = NUM2LONG(size);
/* NUM2LONG() may call size.to_int, ary can be frozen, modified, etc */
if (len < 0) {
rb_raise(rb_eArgError, "negative array size");
}
if (len > ARY_MAX_SIZE) {
rb_raise(rb_eArgError, "array size too big");
}
/* recheck after argument conversion */
rb_ary_modify(ary);
ary_resize_capa(ary, len);
if (rb_block_given_p()) {
long i;
if (argc == 2) {
rb_warn("block supersedes default value argument");
}
for (i=0; i<len; i++) {
rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
ARY_SET_LEN(ary, i + 1);
}
}
else {
ary_memfill(ary, 0, len, val);
ARY_SET_LEN(ary, len);
}
return ary;
}
|
Class Method Details
.[](*args) ⇒ Object
Returns a new array, populated with the given objects:
Array[1, 'a', /^A/] # => [1, "a", /^A/]
Array[] # => []
Array.[](1, 'a', /^A/) # => [1, "a", /^A/]
Related: see Methods for Creating an Array.
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 |
# File 'array.c', line 1188
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;
}
|
.new(*args) ⇒ Object
:nodoc:
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 |
# File 'array.c', line 1050
static VALUE
rb_ary_s_new(int argc, VALUE *argv, VALUE klass)
{
VALUE ary;
if (klass == rb_cArray) {
long size = 0;
if (argc > 0 && FIXNUM_P(argv[0])) {
size = FIX2LONG(argv[0]);
if (size < 0) size = 0;
}
ary = ary_new(klass, size);
rb_obj_call_init_kw(ary, argc, argv, RB_PASS_CALLED_KEYWORDS);
}
else {
ary = rb_class_new_instance_pass_kw(argc, argv, klass);
}
return ary;
}
|
.try_convert(object) ⇒ Object?
Attempts to return an array, based on the given object
.
If object
is an array, returns object
.
Otherwise if object
responds to :to_ary
. calls object.to_ary
: if the return value is an array or nil
, returns that value; if not, raises TypeError.
Otherwise returns nil
.
Related: see Methods for Creating an Array.
1043 1044 1045 1046 1047 |
# File 'array.c', line 1043
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 the intersection of self
and other_array
; that is, containing those elements found in both self
and other_array
:
[0, 1, 2, 3] & [1, 2] # => [1, 2]
Omits duplicates:
[0, 1, 1, 0] & [0, 1] # => [0, 1]
Preserves order from self
:
[0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2]
Identifies common elements using method #eql?
(as defined in each element of self
).
Related: see Methods for Combining.
5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 |
# File 'array.c', line 5646
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);
}
}
return ary3;
}
|
#*(n) ⇒ Object #*(string_separator) ⇒ Object
When non-negative integer argument n
is given, returns a new array built by concatenating n
copies of self
:
a = ['x', 'y']
a * 3 # => ["x", "y", "x", "y", "x", "y"]
When string argument string_separator
is given, equivalent to self.join(string_separator)
:
[0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {foo: 0}"
5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 |
# File 'array.c', line 5091
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(ary);
t = RARRAY_LEN(ary);
if (0 < t) {
ary_memcpy(ary2, 0, t, ptr);
while (t <= len/2) {
ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));
t *= 2;
}
if (t < len) {
ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
}
}
out:
return ary2;
}
|
#+(other_array) ⇒ Object
Returns a new array containing all elements of self
followed by all elements of other_array
:
a = [0, 1] + [2, 3]
a # => [0, 1, 2, 3]
Related: see Methods for Combining.
5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 |
# File 'array.c', line 5004
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(x));
ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));
ARY_SET_LEN(z, len);
return z;
}
|
#-(other_array) ⇒ Object
Returns a new array containing only those elements of self
that are not found in other_array
; the order from self
is preserved:
[0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3]
[0, 1, 1, 2, 1, 1, 3, 1, 1] - [3, 2, 0, :foo] # => [1, 1, 1, 1, 1, 1]
[0, 1, 2] - [:foo] # => [0, 1, 2]
Element are compared using method #eql?
(as defined in each element of self
).
Related: see Methods for Combining.
5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 |
# File 'array.c', line 5537
VALUE
rb_ary_diff(VALUE ary1, VALUE ary2)
{
VALUE ary3;
VALUE hash;
long i;
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary2) == 0) { return ary_make_shared_copy(ary1); }
ary3 = rb_ary_new();
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (i=0; i<RARRAY_LEN(ary1); i++) {
VALUE elt = rb_ary_elt(ary1, i);
if (rb_ary_includes_by_eql(ary2, elt)) continue;
rb_ary_push(ary3, elt);
}
return ary3;
}
hash = ary_make_hash(ary2);
for (i=0; i<RARRAY_LEN(ary1); i++) {
if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
rb_ary_push(ary3, rb_ary_elt(ary1, i));
}
return ary3;
}
|
#<<(object) ⇒ self
Appends object
as the last element in self
; returns self
:
[:foo, 'bar', 2] << :baz # => [:foo, "bar", 2, :baz]
Appends object
as a single element, even if it is another array:
[:foo, 'bar', 2] << [3, 4] # => [:foo, "bar", 2, [3, 4]]
Related: see Methods for Assigning.
1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 |
# File 'array.c', line 1377
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(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 determined to be less than, equal to, or greater than other_array
.
Iterates over each index i
in (0...self.size)
:
-
Computes
result[i]
asself[i] <=> other_array[i]
. -
Immediately returns 1 if
result[i]
is 1:[0, 1, 2] <=> [0, 0, 2] # => 1
-
Immediately returns -1 if
result[i]
is -1:[0, 1, 2] <=> [0, 2, 2] # => -1
-
Continues if
result[i]
is 0.
When every result
is 0, returns self.size <=> other_array.size
(see Integer#<=>):
[0, 1, 2] <=> [0, 1] # => 1
[0, 1, 2] <=> [0, 1, 2] # => 0
[0, 1, 2] <=> [0, 1, 2, 3] # => -1
Note that when other_array
is larger than self
, its trailing elements do not affect the result:
[0, 1, 2] <=> [0, 1, 2, -3] # => -1
[0, 1, 2] <=> [0, 1, 2, 0] # => -1
[0, 1, 2] <=> [0, 1, 2, 3] # => -1
Related: see Methods for Comparing.
5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 |
# File 'array.c', line 5454
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 (!UNDEF_P(v)) return v;
len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
if (len == 0) return INT2FIX(0);
if (len > 0) return INT2FIX(1);
return INT2FIX(-1);
}
|
#==(other_array) ⇒ Boolean
Returns whether both:
-
self
andother_array
are the same size. -
Their corresponding elements are the same; that is, for each index
i
in(0...self.size)
,self[i] == other_array[i]
.
Examples:
[:foo, 'bar', 2] == [:foo, 'bar', 2] # => true
[:foo, 'bar', 2] == [:foo, 'bar', 2.0] # => true
[:foo, 'bar', 2] == [:foo, 'bar'] # => false # Different sizes.
[:foo, 'bar', 2] == [:foo, 'bar', 3] # => false # Different elements.
This method is different from method Array#eql?, which compares elements using Object#eql?
.
Related: see Methods for Comparing.
5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 |
# File 'array.c', line 5257
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(ary1) == RARRAY_CONST_PTR(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
.
In brief:
a = [:foo, 'bar', 2]
# Single argument index: returns one element.
a[0] # => :foo # Zero-based index.
a[-1] # => 2 # Negative index counts backwards from end.
# Arguments start and length: returns an array.
a[1, 2] # => ["bar", 2]
a[-2, 2] # => ["bar", 2] # Negative start counts backwards from end.
# Single argument range: returns an array.
a[0..1] # => [:foo, "bar"]
a[0..-2] # => [:foo, "bar"] # Negative range-begin counts backwards from end.
a[-2..2] # => ["bar", 2] # Negative range-end counts backwards from end.
When a single integer 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 backwards from 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]
Related: see Methods for Fetching.
1888 1889 1890 1891 1892 1893 1894 1895 1896 |
# File 'array.c', line 1888
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
, based on the given object
; returns object
.
In brief:
a_orig = [:foo, 'bar', 2]
# With argument index.
a = a_orig.dup
a[0] = 'foo' # => "foo"
a # => ["foo", "bar", 2]
a = a_orig.dup
a[7] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]
# With arguments start and length.
a = a_orig.dup
a[0, 2] = 'foo' # => "foo"
a # => ["foo", 2]
a = a_orig.dup
a[6, 50] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
# With argument range.
a = a_orig.dup
a[0..1] = 'foo' # => "foo"
a # => ["foo", 2]
a = a_orig.dup
a[6..50] = 'foo' # => "foo"
a # => [:foo, "bar", 2, nil, nil, nil, "foo"]
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 not 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
, extends the array with nil
, 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"]
Related: see Methods for Assigning.
2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 |
# File 'array.c', line 2493
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?(object) ⇒ Boolean #all? {|element| ... } ⇒ Boolean
Returns whether for every element of self
, a given criterion is satisfied.
With no block and no argument, returns whether every element of self
is truthy:
[[], {}, '', 0, 0.0, Object.new].all? # => true # All truthy objects.
[[], {}, '', 0, 0.0, nil].all? # => false # nil is not truthy.
[[], {}, '', 0, 0.0, false].all? # => false # false is not truthy.
With argument object
given, returns whether object === ele
for every element ele
in self
:
[0, 0, 0].all?(0) # => true
[0, 1, 2].all?(1) # => false
['food', 'fool', 'foot'].all?(/foo/) # => true
['food', 'drink'].all?(/foo/) # => false
With a block given, calls the block with each element in self
; returns whether the block returns only truthy values:
[0, 1, 2].all? { |ele| ele < 3 } # => true
[0, 1, 2].all? { |ele| ele < 2 } # => false
With both a block and argument object
given, ignores the block and uses object
as above.
Special case: returns true
if self
is empty (regardless of any given argument or block).
Related: see Methods for Querying.
7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 |
# File 'array.c', line 7850
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?(object) ⇒ Boolean #any? {|element| ... } ⇒ Boolean
Returns whether for any element of self
, a given criterion is satisfied.
With no block and no argument, returns whether any element of self
is truthy:
[nil, false, []].any? # => true # Array object is truthy.
[nil, false, {}].any? # => true # Hash object is truthy.
[nil, false, ''].any? # => true # String object is truthy.
[nil, false].any? # => false # Nil and false are not truthy.
With argument object
given, returns whether object === ele
for any element ele
in self
:
[nil, false, 0].any?(0) # => true
[nil, false, 1].any?(0) # => false
[nil, false, 'food'].any?(/foo/) # => true
[nil, false, 'food'].any?(/bar/) # => false
With a block given, calls the block with each element in self
; returns whether the block returns any truthy value:
[0, 1, 2].any? {|ele| ele < 1 } # => true
[0, 1, 2].any? {|ele| ele < 0 } # => false
With both a block and argument object
given, ignores the block and uses object
as above.
Special case: returns false
if self
is empty (regardless of any given argument or block).
Related: see Methods for Querying.
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 |
# File 'array.c', line 7783
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(object) ⇒ nil
Returns the first element ele
in self
such that ele
is an array and ele[0] == object
:
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: Array#rassoc; see also Methods for Fetching.
5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 |
# File 'array.c', line 5151
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 of self
specified by the given index
or nil
if there is no such element; index
must be an integer-convertible object.
For non-negative index
, returns the element of self
at offset index
:
a = [:foo, 'bar', 2]
a.at(0) # => :foo
a.at(2) # => 2
a.at(2.0) # => 2
For negative index
, counts backwards from the end of self
:
a.at(-2) # => "bar"
Related: Array#[]; see also Methods for Fetching.
1955 1956 1957 1958 1959 |
# File 'array.c', line 1955
VALUE
rb_ary_at(VALUE ary, VALUE pos)
{
return rb_ary_entry(ary, NUM2LONG(pos));
}
|
#bsearch {|element| ... } ⇒ nil #bsearch ⇒ Object
Returns the element from self
found by a binary search, or nil
if the search found no suitable element.
See Binary Searching.
Related: see Methods for Fetching.
3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 |
# File 'array.c', line 3503
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
Returns the integer index of the element from self
found by a binary search, or nil
if the search found no suitable element.
See Binary Searching.
Related: see Methods for Fetching.
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 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 |
# File 'array.c', line 3527
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 (!RTEST(v)) {
smaller = 0;
}
else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
const VALUE zero = INT2FIX(0);
switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
case 0: return INT2FIX(mid);
case 1: smaller = 0; break;
case -1: smaller = 1;
}
}
else {
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
" (must be numeric, true, false or nil)",
rb_obj_class(v));
}
if (smaller) {
high = mid;
}
else {
low = mid + 1;
}
}
if (!satisfied) return Qnil;
return INT2FIX(low);
}
|
#clear ⇒ self
Removes all elements from self
; returns self
:
a = [:foo, 'bar', 2]
a.clear # => []
Related: see Methods for Deleting.
4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 |
# File 'array.c', line 4728
VALUE
rb_ary_clear(VALUE ary)
{
rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
ARY_SET_EMBED_LEN(ary, 0);
}
else {
ARY_SET_LEN(ary, 0);
if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
}
}
ary_verify(ary);
return ary;
}
|
#collect {|element| ... } ⇒ Object #collect ⇒ Object #map {|element| ... } ⇒ Object #map ⇒ Object
With a block given, calls the block 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]
With no block given, returns a new Enumerator.
Related: #collect!; see also Methods for Converting.
3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 |
# File 'array.c', line 3636
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;
}
|
#collect! {|element| ... } ⇒ Object #collect! ⇒ Object #map! {|element| ... } ⇒ Object #map! ⇒ Object
With a block given, calls the block with each element of self
and replaces the element with the block’s return value; returns self
:
a = [:foo, 'bar', 2]
a.map! { |element| element.class } # => [Symbol, String, Integer]
With no block given, returns a new Enumerator.
Related: #collect; see also Methods for Converting.
3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 |
# File 'array.c', line 3671
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(count) {|element| ... } ⇒ self #combination(count) ⇒ Object
When a block and a positive integer-convertible object argument count
(0 < count <= self.size
) are given, calls the block with each combination of self
of size count
; returns self
:
a = %w[a b c] # => ["a", "b", "c"]
a.combination(2) {|combination| p combination } # => ["a", "b", "c"]
Output:
["a", "b"]
["a", "c"]
["b", "c"]
The order of the yielded combinations is not guaranteed.
When count
is zero, calls the block once with a new empty array:
a.combination(0) {|combination| p combination }
[].combination(0) {|combination| p combination }
Output:
[]
[]
When count
is negative or larger than self.size
and self
is non-empty, does not call the block:
a.combination(-1) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"]
a.combination(4) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"]
With no block given, returns a new Enumerator.
Related: Array#permutation; see also Methods for Iterating.
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 |
# File 'array.c', line 7218
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 only the non-nil
elements from self
; element order is preserved:
a = [nil, 0, nil, false, nil, '', nil, [], nil, {}]
a.compact # => [0, false, "", [], {}]
Related: Array#compact!; see also Methods for Deleting.
6433 6434 6435 6436 6437 6438 6439 |
# File 'array.c', line 6433
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 are removed, nil
otherwise:
a = [nil, 0, nil, false, nil, '', nil, [], nil, {}]
a.compact! # => [0, false, "", [], {}]
a # => [0, false, "", [], {}]
a.compact! # => nil
Related: Array#compact; see also Methods for Deleting.
6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 |
# File 'array.c', line 6396
static VALUE
rb_ary_compact_bang(VALUE ary)
{
VALUE *p, *t, *end;
long n;
rb_ary_modify(ary);
p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */
end = p + RARRAY_LEN(ary);
while (t < end) {
if (NIL_P(*t)) t++;
else *p++ = *t++;
}
n = p - RARRAY_CONST_PTR(ary);
if (RARRAY_LEN(ary) == n) {
return Qnil;
}
ary_resize_smaller(ary, n);
return ary;
}
|
#concat(*other_arrays) ⇒ self
Adds to self
all elements from each array in other_arrays
; returns self
:
a = [0, 1]
a.concat(['two', 'three'], [:four, :five], a)
# => [0, 1, "two", "three", :four, :five, 0, 1]
Related: see Methods for Assigning.
5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 |
# File 'array.c', line 5046
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_hidden_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(object) ⇒ Integer #count {|element| ... } ⇒ Integer
Returns a count of specified elements.
With no argument and no block, returns the count of all elements:
[0, :one, 'two', 3, 3.0].count # => 5
With argument object
given, returns the count of elements ==
to object
:
[0, :one, 'two', 3, 3.0].count(3) # => 2
With no argument and a block given, calls the block with each element; returns the count of elements for which the block returns a truthy value:
[0, 1, 2, 3].count {|element| element > 1 } # => 2
With argument object
and a block given, issues a warning, ignores the block, and returns the count of elements ==
to object
.
Related: see Methods for Querying.
6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 |
# File 'array.c', line 6468
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(count = nil) {|element| ... } ⇒ nil #cycle(count = nil) ⇒ Object
With a block given, may call the block, depending on the value of argument count
; count
must be an integer-convertible object, or nil
.
When count
is positive, calls the block with each element, then does so repeatedly, until it has done so count
times; returns nil
:
output = []
[0, 1].cycle(2) {|element| output.push(element) } # => nil
output # => [0, 1, 0, 1]
When 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 count
is nil
, cycles forever:
# Prints 0 and 1 forever.
[0, 1].cycle {|element| puts element }
[0, 1].cycle(nil) {|element| puts element }
With no block given, returns a new Enumerator.
Related: see Methods for Iterating.
6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 |
# File 'array.c', line 6924
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
:nodoc:
8216 8217 8218 8219 8220 |
# File 'array.c', line 8216
static VALUE
rb_ary_deconstruct(VALUE ary)
{
return ary;
}
|
#delete(object) ⇒ Object #delete(object) {|element| ... } ⇒ Object
Removes zero or more elements from self
.
With no block given, removes from self
each element ele
such that ele == object
; returns the last removed element:
a = [0, 1, 2, 2.0]
a.delete(2) # => 2.0
a # => [0, 1]
Returns nil
if no elements removed:
a.delete(2) # => nil
With a block given, removes from self
each element ele
such that ele == object
.
If any such elements are found, ignores the block and returns the last removed element:
a = [0, 1, 2, 2.0]
a.delete(2) {|element| fail 'Cannot happen' } # => 2.0
a # => [0, 1]
If no such element is found, returns the block’s return value:
a.delete(2) {|element| "Element #{element} not found." }
# => "Element 2 not found."
Related: see Methods for Deleting.
4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 |
# File 'array.c', line 4047
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
Removes the element of self
at the given index
, which must be an integer-convertible object.
When index
is non-negative, deletes the element at offset index
:
a = [:foo, 'bar', 2]
a.delete_at(1) # => "bar"
a # => [:foo, 2]
When index
is negative, counts backward from the end of the array:
a = [:foo, 'bar', 2]
a.delete_at(-2) # => "bar"
a # => [:foo, 2]
When index
is out of range, returns nil
.
a = [:foo, 'bar', 2]
a.delete_at(3) # => nil
a.delete_at(-4) # => nil
Related: see Methods for Deleting.
4151 4152 4153 4154 4155 |
# File 'array.c', line 4151
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 ⇒ Object
With a block given, calls the block with each element of self
; removes the element if 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]
With no block given, returns a new Enumerator.
Related: see Methods for Deleting.
4428 4429 4430 4431 4432 4433 4434 4435 |
# File 'array.c', line 4428
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 given 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]
[0, 1, 2].difference # => [0, 1, 2]
Returns a copy of self
if no arguments are given.
Related: Array#-; see also Methods for Combining.
5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 |
# File 'array.c', line 5585
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 object 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
Related: see Methods for Fetching.
8033 8034 8035 8036 8037 8038 8039 8040 8041 |
# File 'array.c', line 8033
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(count) ⇒ Object
Returns a new array containing all but the first count
element of self
, where count
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]
a.drop(9) # => []
Related: see Methods for Fetching.
7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 |
# File 'array.c', line 7700
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 (NIL_P(result)) result = rb_ary_new();
return result;
}
|
#drop_while {|element| ... } ⇒ Object #drop_while ⇒ Object
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; does not modify self
:
a = [0, 1, 2, 3, 4, 5]
a.drop_while {|element| element < 3 } # => [3, 4, 5]
With no block given, returns a new Enumerator.
Related: see Methods for Fetching.
7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 |
# File 'array.c', line 7732
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 ⇒ Object
With a block given, iterates over the elements of self
, passing each 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
With no block given, returns a new Enumerator.
Related: see Methods for Iterating.
2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 |
# File 'array.c', line 2634
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 ⇒ Object
With a block given, iterates over the elements of self
, passing each 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 }
a # => []
Output:
0
1
With no block given, returns a new Enumerator.
Related: see Methods for Iterating.
2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 |
# File 'array.c', line 2680
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.
Related: see Methods for Querying.
2764 2765 2766 2767 2768 |
# File 'array.c', line 2764
static VALUE
rb_ary_empty_p(VALUE ary)
{
return RBOOL(RARRAY_LEN(ary) == 0);
}
|
#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#==
.
Related: see Methods for Querying.
5304 5305 5306 5307 5308 5309 5310 5311 5312 |
# File 'array.c', line 5304
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(ary1) == RARRAY_CONST_PTR(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 of self
at offset index
if index
is in range; index
must be an integer-convertible object.
With the single argument index
and no block, returns the element at offset index
:
a = [:foo, 'bar', 2]
a.fetch(1) # => "bar"
a.fetch(1.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
(which may be any object) and no block, returns default_value
if index
is out-of-range:
a = [:foo, 'bar', 2]
a.fetch(1, nil) # => "bar"
a.fetch(3, :foo) # => :foo
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"
Related: see Methods for Fetching.
2039 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 |
# File 'array.c', line 2039
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(object, start = nil, count = nil) ⇒ Object #fill(object, range) ⇒ Object #fill(start = nil, count = nil) {|element| ... } ⇒ Object #fill(range) {|element| ... } ⇒ Object
Replaces selected elements in self
; may add elements to self
; always returns self
(never a new array).
In brief:
# Non-negative start.
['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"]
['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"]
# Extends with specified values if necessary.
['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"]
['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"]
# Fills with nils if necessary.
['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"]
['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"]
# For negative start, counts backwards from the end.
['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"]
['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"]
# Range.
['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"]
['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"]
When arguments start
and count
are given, they select the elements of self
to be replaced; each must be an integer-convertible object (or nil
):
-
start
specifies the zero-based offset of the first element to be replaced;nil
means zero. -
count
is the number of consecutive elements to be replaced;nil
means “all the rest.”
With argument object
given, that one object is used for all replacements:
o = Object.new # => #<Object:0x0000014e7bff7600>
a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"]
a.fill(o, 1, 2)
# => ["a", #<Object:0x0000014e7bff7600>, #<Object:0x0000014e7bff7600>, "d"]
With a block given, the block is called once for each element to be replaced; the value passed to the block is the index of the element to be replaced (not the element itself); the block’s return value replaces the element:
a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"]
a.fill(1, 2) {|element| element.to_s } # => ["a", "1", "2", "d"]
For arguments start
and count
:
-
If
start
is non-negative, replacescount
elements beginning at offsetstart
:['a', 'b', 'c', 'd'].fill('-', 0, 2) # => ["-", "-", "c", "d"] ['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill('-', 2, 2) # => ["a", "b", "-", "-"] ['a', 'b', 'c', 'd'].fill(0, 2) {|e| e.to_s } # => ["0", "1", "c", "d"] ['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"] ['a', 'b', 'c', 'd'].fill(2, 2) {|e| e.to_s } # => ["a", "b", "2", "3"]
Extends
self
if necessary:['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"] ['a', 'b', 'c', 'd'].fill('-', 4, 2) # => ["a", "b", "c", "d", "-", "-"] ['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"] ['a', 'b', 'c', 'd'].fill(4, 2) {|e| e.to_s } # => ["a", "b", "c", "d", "4", "5"]
Fills with
nil
if necessary:['a', 'b', 'c', 'd'].fill('-', 5, 2) # => ["a", "b", "c", "d", nil, "-", "-"] ['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"] ['a', 'b', 'c', 'd'].fill(5, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, "5", "6"] ['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"]
Does nothing if
count
is non-positive:['a', 'b', 'c', 'd'].fill('-', 2, 0) # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill('-', 2, -100) # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill('-', 6, -100) # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill(2, 0) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill(2, -100) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill(6, -100) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
-
If
start
is negative, counts backwards from the end ofself
:['a', 'b', 'c', 'd'].fill('-', -4, 3) # => ["-", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"] ['a', 'b', 'c', 'd'].fill(-4, 3) {|e| e.to_s } # => ["0", "1", "2", "d"] ['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"]
Extends
self
if necessary:['a', 'b', 'c', 'd'].fill('-', -2, 3) # => ["a", "b", "-", "-", "-"] ['a', 'b', 'c', 'd'].fill('-', -1, 3) # => ["a", "b", "c", "-", "-", "-"] ['a', 'b', 'c', 'd'].fill(-2, 3) {|e| e.to_s } # => ["a", "b", "2", "3", "4"] ['a', 'b', 'c', 'd'].fill(-1, 3) {|e| e.to_s } # => ["a", "b", "c", "3", "4", "5"]
Starts at the beginning of
self
ifstart
is negative and out-of-range:['a', 'b', 'c', 'd'].fill('-', -5, 2) # => ["-", "-", "c", "d"] ['a', 'b', 'c', 'd'].fill('-', -6, 2) # => ["-", "-", "c", "d"] ['a', 'b', 'c', 'd'].fill(-5, 2) {|e| e.to_s } # => ["0", "1", "c", "d"] ['a', 'b', 'c', 'd'].fill(-6, 2) {|e| e.to_s } # => ["0", "1", "c", "d"]
Does nothing if
count
is non-positive:['a', 'b', 'c', 'd'].fill('-', -2, 0) # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill('-', -2, -1) # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill(-2, 0) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill(-2, -1) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"]
When argument range
is given, it must be a Range object whose members are numeric; its begin
and end
values determine the elements of self
to be replaced:
-
If both
begin
andend
are positive, they specify the first and last elements to be replaced:['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"]
If
end
is smaller thanbegin
, replaces no elements:['a', 'b', 'c', 'd'].fill('-', 2..1) # => ["a", "b", "c", "d"] ['a', 'b', 'c', 'd'].fill(2..1) {|e| e.to_s } # => ["a", "b", "c", "d"]
-
If either is negative (or both are negative), counts backwards from the end of
self
:['a', 'b', 'c', 'd'].fill('-', -3..2) # => ["a", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill('-', 1..-2) # => ["a", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill('-', -3..-2) # => ["a", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill(-3..2) {|e| e.to_s } # => ["a", "1", "2", "d"] ['a', 'b', 'c', 'd'].fill(1..-2) {|e| e.to_s } # => ["a", "1", "2", "d"] ['a', 'b', 'c', 'd'].fill(-3..-2) {|e| e.to_s } # => ["a", "1", "2", "d"]
-
If the
end
value is excluded (see Range#exclude_end?), omits the last replacement:['a', 'b', 'c', 'd'].fill('-', 1...2) # => ["a", "-", "c", "d"] ['a', 'b', 'c', 'd'].fill('-', 1...-2) # => ["a", "-", "c", "d"] ['a', 'b', 'c', 'd'].fill(1...2) {|e| e.to_s } # => ["a", "1", "c", "d"] ['a', 'b', 'c', 'd'].fill(1...-2) {|e| e.to_s } # => ["a", "1", "c", "d"]
-
If the range is endless (see Endless Ranges), replaces elements to the end of
self
:['a', 'b', 'c', 'd'].fill('-', 1..) # => ["a", "-", "-", "-"] ['a', 'b', 'c', 'd'].fill(1..) {|e| e.to_s } # => ["a", "1", "2", "3"]
-
If the range is beginless (see Beginless Ranges), replaces elements from the beginning of
self
:['a', 'b', 'c', 'd'].fill('-', ..2) # => ["-", "-", "-", "d"] ['a', 'b', 'c', 'd'].fill(..2) {|e| e.to_s } # => ["0", "1", "2", "d"]
Related: see Methods for Assigning.
4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 |
# File 'array.c', line 4927
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 (UNDEF_P(item)) {
VALUE v;
long i;
for (i=beg; i<end; i++) {
v = rb_yield(LONG2NUM(i));
if (i>=RARRAY_LEN(ary)) break;
ARY_SET(ary, i, v);
}
}
else {
ary_memfill(ary, beg, len, item);
}
return ary;
}
|
#select {|element| ... } ⇒ Object #select ⇒ Object #filter {|element| ... } ⇒ Object #filter ⇒ Object
With a block given, calls the block 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]
a.select {|element| element.to_s.start_with?('b') }
# => ["bar", :bam]
With no block given, returns a new Enumerator.
Related: see Methods for Fetching.
3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 |
# File 'array.c', line 3877
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 #filter! {|element| ... } ⇒ self? #filter! ⇒ Object
With a block given, calls the block 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.
With no block given, returns a new Enumerator.
Related: see Methods for Deleting.
3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 |
# File 'array.c', line 3960
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);
}
|
#find_index(object) ⇒ Integer? #find_index {|element| ... } ⇒ Integer? #find_index ⇒ Object #index(object) ⇒ Integer? #index {|element| ... } ⇒ Integer? #index ⇒ Object
Returns the zero-based integer index of a specified element, or nil
.
With only argument object
given, 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.
With only a block given, calls the block with each successive element; returns the index of the first element for which the block returns a truthy value:
a = [:foo, 'bar', 2, 'bar']
a.index {|element| element == 'bar' } # => 1
Returns nil
if the block never returns a truthy value.
With neither an argument nor a block given, returns a new Enumerator.
Related: see Methods for Querying.
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 |
# File 'array.c', line 2101
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;
}
|
#flatten(depth = nil) ⇒ Object
Returns a new array that is a recursive flattening of self
to depth
levels of recursion; depth
must be an integer-convertible object or nil
. At each level of recursion:
-
Each element that is an array is “flattened” (that is, replaced by its individual array elements).
-
Each element that is not an array is unchanged (even if the element is an object that has instance method
flatten
).
With non-negative integer argument depth
, flattens recursively through depth
levels:
a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ]
a # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
a.flatten(0) # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
a.flatten(1 ) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
a.flatten(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
a.flatten(2) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
a.flatten(3) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
With nil
or negative depth
, flattens all levels.
a.flatten # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
a.flatten(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
Related: Array#flatten!; see also Methods for Converting.
6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 |
# File 'array.c', line 6675
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!(depth = nil) ⇒ self?
Returns self
as a recursively flattening of self
to depth
levels of recursion; depth
must be an integer-convertible object, or nil
. At each level of recursion:
-
Each element that is an array is “flattened” (that is, replaced by its individual array elements).
-
Each element that is not an array is unchanged (even if the element is an object that has instance method
flatten
).
Returns nil
if no elements were flattened.
With non-negative integer argument depth
, flattens recursively through depth
levels:
a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ]
a # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
a.dup.flatten!(1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
a.dup.flatten!(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
a.dup.flatten!(2) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
a.dup.flatten!(3) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
With nil
or negative argument depth
, flattens all levels:
a.dup.flatten! # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
a.dup.flatten!(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
Related: Array#flatten; see also Methods for Assigning.
6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 |
# File 'array.c', line 6618
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_ary_freeze(result);
rb_ary_replace(ary, result);
if (mod) ARY_SET_EMBED_LEN(result, 0);
return ary;
}
|
#freeze ⇒ self
Freezes self
(if not already frozen); returns self
:
a = []
a.frozen? # => false
a.freeze
a.frozen? # => true
No further changes may be made to self
; raises FrozenError if a change is attempted.
Related: Kernel#frozen?.
641 642 643 644 645 646 647 648 649 650 651 652 653 |
# File 'array.c', line 641
VALUE
rb_ary_freeze(VALUE ary)
{
RUBY_ASSERT(RB_TYPE_P(ary, T_ARRAY));
if (OBJ_FROZEN(ary)) return ary;
if (!ARY_EMBED_P(ary) && !ARY_SHARED_P(ary) && !ARY_SHARED_ROOT_P(ary)) {
ary_shrink_capa(ary);
}
return rb_obj_freeze(ary);
}
|
#hash ⇒ Integer
Returns the integer hash value for self
.
Two arrays with the same content will have the same hash value (and will compare using eql?):
['a', 'b'].hash == ['a', 'b'].hash # => true
['a', 'b'].hash == ['a', 'c'].hash # => false
['a', 'b'].hash == ['a'].hash # => false
5346 5347 5348 5349 5350 |
# File 'array.c', line 5346
static VALUE
rb_ary_hash(VALUE ary)
{
return rb_ary_hash_values(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
}
|
#include?(object) ⇒ Boolean
Returns whether for some element element
in self
, object == element
:
[0, 1, 2].include?(2) # => true
[0, 1, 2].include?(2.0) # => true
[0, 1, 2].include?(2.1) # => false
Related: see Methods for Querying.
5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 |
# File 'array.c', line 5366
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;
}
|
#find_index(object) ⇒ Integer? #find_index {|element| ... } ⇒ Integer? #find_index ⇒ Object #index(object) ⇒ Integer? #index {|element| ... } ⇒ Integer? #index ⇒ Object
Returns the zero-based integer index of a specified element, or nil
.
With only argument object
given, 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.
With only a block given, calls the block with each successive element; returns the index of the first element for which the block returns a truthy value:
a = [:foo, 'bar', 2, 'bar']
a.index {|element| element == 'bar' } # => 1
Returns nil
if the block never returns a truthy value.
With neither an argument nor a block given, returns a new Enumerator.
Related: see Methods for Querying.
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 |
# File 'array.c', line 2101
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;
}
|
#initialize_copy(other_array) ⇒ self #replace(other_array) ⇒ self
Replaces the elements of self
with the elements of other_array
, which must be an array-convertible object; returns self
:
a = ['a', 'b', 'c'] # => ["a", "b", "c"]
a.replace(['d', 'e']) # => ["d", "e"]
Related: see Methods for Assigning.
4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 |
# File 'array.c', line 4673
VALUE
rb_ary_replace(VALUE copy, VALUE orig)
{
rb_ary_modify_check(copy);
orig = to_ary(orig);
if (copy == orig) return copy;
rb_ary_reset(copy);
/* orig has enough space to embed the contents of orig. */
if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
RUBY_ASSERT(ARY_EMBED_P(copy));
ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));
ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig));
}
/* orig is embedded but copy does not have enough space to embed the
* contents of orig. */
else if (ARY_EMBED_P(orig)) {
long len = ARY_EMBED_LEN(orig);
VALUE *ptr = ary_heap_alloc_buffer(len);
FL_UNSET_EMBED(copy);
ARY_SET_PTR(copy, ptr);
ARY_SET_LEN(copy, len);
ARY_SET_CAPA(copy, len);
// No allocation and exception expected that could leave `copy` in a
// bad state from the edits above.
ary_memcpy(copy, 0, len, RARRAY_CONST_PTR(orig));
}
/* Otherwise, orig is on heap and copy does not have enough space to embed
* the contents of orig. */
else {
VALUE shared_root = ary_make_shared(orig);
FL_UNSET_EMBED(copy);
ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
rb_ary_set_shared(copy, shared_root);
}
ary_verify(copy);
return copy;
}
|
#insert(index, *objects) ⇒ self
Inserts the given objects
as elements of self
; returns self
.
When index
is non-negative, inserts objects
before the element at offset index
:
a = ['a', 'b', 'c'] # => ["a", "b", "c"]
a.insert(1, :x, :y, :z) # => ["a", :x, :y, :z, "b", "c"]
Extends the array if index
is beyond the array (index >= self.size
):
a = ['a', 'b', 'c'] # => ["a", "b", "c"]
a.insert(5, :x, :y, :z) # => ["a", "b", "c", nil, nil, :x, :y, :z]
When index
is negative, inserts objects
after the element at offset index + self.size
:
a = ['a', 'b', 'c'] # => ["a", "b", "c"]
a.insert(-2, :x, :y, :z) # => ["a", "b", :x, :y, :z, "c"]
With no objects
given, does nothing:
a = ['a', 'b', 'c'] # => ["a", "b", "c"]
a.insert(1) # => ["a", "b", "c"]
a.insert(50) # => ["a", "b", "c"]
a.insert(-50) # => ["a", "b", "c"]
Raises IndexError if objects
are given and index
is negative and out of range.
Related: see Methods for Assigning.
2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 |
# File 'array.c', line 2554
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 #to_s ⇒ 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]"
Related: see Methods for Converting.
2999 3000 3001 3002 3003 3004 |
# File 'array.c', line 2999
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);
}
|
#intersect?(other_array) ⇒ Boolean
Returns whether other_array
has at least one element that is #eql?
to some element of self
:
[1, 2, 3].intersect?([3, 4, 5]) # => true
[1, 2, 3].intersect?([4, 5, 6]) # => false
Each element must correctly implement method #hash
.
Related: see Methods for Querying.
5844 5845 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 |
# File 'array.c', line 5844
static VALUE
rb_ary_intersect_p(VALUE ary1, VALUE ary2)
{
VALUE hash, v, result, shorter, longer;
st_data_t vv;
long i;
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return Qfalse;
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (i=0; i<RARRAY_LEN(ary1); i++) {
v = RARRAY_AREF(ary1, i);
if (rb_ary_includes_by_eql(ary2, v)) return Qtrue;
}
return Qfalse;
}
shorter = ary1;
longer = ary2;
if (RARRAY_LEN(ary1) > RARRAY_LEN(ary2)) {
longer = ary1;
shorter = ary2;
}
hash = ary_make_hash(shorter);
result = Qfalse;
for (i=0; i<RARRAY_LEN(longer); i++) {
v = RARRAY_AREF(longer, i);
vv = (st_data_t)v;
if (rb_hash_stlike_lookup(hash, vv, 0)) {
result = Qtrue;
break;
}
}
return result;
}
|
#intersection(*other_arrays) ⇒ Object
Returns a new array containing each element in self
that is #eql?
to at least one element in each of the given other_arrays
; duplicates are omitted:
[0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]
Each element must correctly implement method #hash
.
Order from self
is preserved:
[0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2]
Returns a copy of self
if no arguments are given.
Related: see Methods for Combining.
5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 |
# File 'array.c', line 5701
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;
}
|
#join(separator = $,) ⇒ Object
Returns the new string formed by joining the converted elements of self
; for each element element
:
-
Converts recursively using
element.join(separator)
ifelement
is akind_of?(Array)
. -
Otherwise, converts using
element.to_s
.
With no argument given, joins using the output field separator, $,
:
a = [:foo, 'bar', 2]
$, # => nil
a.join # => "foobar2"
With string argument separator
given, joins using that separator:
a = [:foo, 'bar', 2]
a.join("\n") # => "foo\nbar\n2"
Joins recursively for nested arrays:
a = [:foo, [:bar, [:baz, :bat]]]
a.join # => "foobarbazbat"
Related: see Methods for Converting.
2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 |
# File 'array.c', line 2952
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
With a block given, calls the block with each element of self
; removes the element from self
if the block does not return a truthy value:
a = [:foo, 'bar', 2, :bam]
a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam]
With no block given, returns a new Enumerator.
Related: see Methods for Deleting.
3989 3990 3991 3992 3993 3994 3995 |
# File 'array.c', line 3989
static VALUE
rb_ary_keep_if(VALUE ary)
{
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
rb_ary_select_bang(ary);
return ary;
}
|
#length ⇒ Integer #size ⇒ Integer
Returns the count of elements in self
:
[0, 1, 2].length # => 3
[].length # => 0
Related: see Methods for Querying.
2747 2748 2749 2750 2751 2752 |
# File 'array.c', line 2747
static VALUE
rb_ary_length(VALUE ary)
{
long len = RARRAY_LEN(ary);
return LONG2NUM(len);
}
|
#collect {|element| ... } ⇒ Object #collect ⇒ Object #map {|element| ... } ⇒ Object #map ⇒ Object
With a block given, calls the block 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]
With no block given, returns a new Enumerator.
Related: #collect!; see also Methods for Converting.
3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 |
# File 'array.c', line 3636
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;
}
|
#collect! {|element| ... } ⇒ Object #collect! ⇒ Object #map! {|element| ... } ⇒ Object #map! ⇒ Object
With a block given, calls the block with each element of self
and replaces the element with the block’s return value; returns self
:
a = [:foo, 'bar', 2]
a.map! { |element| element.class } # => [Symbol, String, Integer]
With no block given, returns a new Enumerator.
Related: #collect; see also Methods for Converting.
3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 |
# File 'array.c', line 3671
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(count) ⇒ Object #max {|a, b| ... } ⇒ Object #max(count) {|a, b| ... } ⇒ Object
Returns one of the following:
-
The maximum-valued element from
self
. -
A new array of maximum-valued elements from
self
.
Does not modify self
.
With no block given, each element in self
must respond to method #<=>
with a numeric.
With no argument and no block, returns the element in self
having the maximum value per method #<=>
:
[1, 0, 3, 2].max # => 3
With non-negative numeric argument count
and no block, returns a new array with at most count
elements, in descending order, per method #<=>
:
[1, 0, 3, 2].max(3) # => [3, 2, 1]
[1, 0, 3, 2].max(3.0) # => [3, 2, 1]
[1, 0, 3, 2].max(9) # => [3, 2, 1, 0]
[1, 0, 3, 2].max(0) # => []
With a block given, the block must return a numeric.
With a block and no argument, calls the block self.size - 1
times to compare elements; returns the element having the maximum value per the block:
['0', '', '000', '00'].max {|a, b| a.size <=> b.size }
# => "000"
With non-negative numeric argument count
and a block, returns a new array with at most count
elements, in descending order, per the block:
['0', '', '000', '00'].max(2) {|a, b| a.size <=> b.size }
# => ["000", "00"]
Related: see Methods for Fetching.
6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 |
# File 'array.c', line 6021
static VALUE
rb_ary_max(int argc, VALUE *argv, VALUE ary)
{
VALUE result = Qundef, v;
VALUE num;
long i;
if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(ary, num, 0, 1, 1);
const long n = RARRAY_LEN(ary);
if (rb_block_given_p()) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
v = RARRAY_AREF(ary, i);
if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
result = v;
}
}
}
else if (n > 0) {
result = RARRAY_AREF(ary, 0);
if (n > 1) {
if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
return ary_max_opt_fixnum(ary, 1, result);
}
else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
return ary_max_opt_string(ary, 1, result);
}
else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
return ary_max_opt_float(ary, 1, result);
}
else {
return ary_max_generic(ary, 1, result);
}
}
}
if (UNDEF_P(result)) return Qnil;
return result;
}
|
#min ⇒ Object #min(count) ⇒ Object #min {|a, b| ... } ⇒ Object #min(count) {|a, b| ... } ⇒ Object
Returns one of the following:
-
The minimum-valued element from
self
. -
A new array of minimum-valued elements from
self
.
Does not modify self
.
With no block given, each element in self
must respond to method #<=>
with a numeric.
With no argument and no block, returns the element in self
having the minimum value per method #<=>
:
[1, 0, 3, 2].min # => 0
With non-negative numeric argument count
and no block, returns a new array with at most count
elements, in ascending order, per method #<=>
:
[1, 0, 3, 2].min(3) # => [0, 1, 2]
[1, 0, 3, 2].min(3.0) # => [0, 1, 2]
[1, 0, 3, 2].min(9) # => [0, 1, 2, 3]
[1, 0, 3, 2].min(0) # => []
With a block given, the block must return a numeric.
With a block and no argument, calls the block self.size - 1
times to compare elements; returns the element having the minimum value per the block:
['0', '', '000', '00'].min {|a, b| a.size <=> b.size }
# => ""
With non-negative numeric argument count
and a block, returns a new array with at most count
elements, in ascending order, per the block:
['0', '', '000', '00'].min(2) {|a, b| a.size <=> b.size }
# => ["", "0"]
Related: see Methods for Fetching.
6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 |
# File 'array.c', line 6198
static VALUE
rb_ary_min(int argc, VALUE *argv, VALUE ary)
{
VALUE result = Qundef, v;
VALUE num;
long i;
if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
return rb_nmin_run(ary, num, 0, 0, 1);
const long n = RARRAY_LEN(ary);
if (rb_block_given_p()) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
v = RARRAY_AREF(ary, i);
if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
result = v;
}
}
}
else if (n > 0) {
result = RARRAY_AREF(ary, 0);
if (n > 1) {
if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
return ary_min_opt_fixnum(ary, 1, result);
}
else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
return ary_min_opt_string(ary, 1, result);
}
else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
return ary_min_opt_float(ary, 1, result);
}
else {
return ary_min_generic(ary, 1, result);
}
}
}
if (UNDEF_P(result)) return Qnil;
return result;
}
|
#minmax ⇒ Array #minmax {|a, b| ... } ⇒ Array
Returns a 2-element array containing the minimum-valued and maximum-valued elements from self
; does not modify self
.
With no block given, the minimum and maximum values are determined using method #<=>
:
[1, 0, 3, 2].minmax # => [0, 3]
With a block given, the block must return a numeric; the block is called self.size - 1
times to compare elements; returns the elements having the minimum and maximum values per the block:
['0', '', '000', '00'].minmax {|a, b| a.size <=> b.size }
# => ["", "000"]
Related: see Methods for Fetching.
6260 6261 6262 6263 6264 6265 6266 6267 |
# File 'array.c', line 6260
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?(object) ⇒ Boolean #none? {|element| ... } ⇒ Boolean
Returns true
if no element of self
meets a given criterion, false
otherwise.
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 argument object
given, returns false
if for any element element
, object === element
; true
otherwise:
['food', 'drink'].none?(/bar/) # => true
['food', 'drink'].none?(/foo/) # => false
[].none?(/foo/) # => true
[0, 1, 2].none?(3) # => true
[0, 1, 2].none?(1) # => false
With a block given, calls the block with each element 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
Related: see Methods for Querying.
7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 |
# File 'array.c', line 7911
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?(object) ⇒ 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, 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
With argument object
given, returns true
if for exactly one element element
, object === element
; false
otherwise:
[0, 1, 2].one?(0) # => true
[0, 0, 1].one?(0) # => false
[1, 1, 2].one?(0) # => false
['food', 'drink'].one?(/bar/) # => false
['food', 'drink'].one?(/foo/) # => true
[].one?(/foo/) # => false
Related: see Methods for Querying.
7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 |
# File 'array.c', line 7975
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(count = self.size) {|permutation| ... } ⇒ self #permutation(count = self.size) ⇒ Object
Iterates over permutations of the elements of self
; the order of permutations is indeterminate.
With a block and an in-range positive integer argument count
(0 < count <= self.size
) given, calls the block with each permutation of self
of size count
; returns self
:
a = [0, 1, 2]
perms = []
a.permutation(1) {|perm| perms.push(perm) }
perms # => [[0], [1], [2]]
perms = []
a.permutation(2) {|perm| perms.push(perm) }
perms # => [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]]
perms = []
a.permutation(3) {|perm| perms.push(perm) }
perms # => [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]
When count
is zero, calls the block once with a new empty array:
perms = []
a.permutation(0) {|perm| perms.push(perm) }
perms # => [[]]
When count
is out of range (negative or larger than self.size
), does not call the block:
a.permutation(-1) {|permutation| fail 'Cannot happen' }
a.permutation(4) {|permutation| fail 'Cannot happen' }
With no block given, returns a new Enumerator.
Related: Methods for Iterating.
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 7134 7135 7136 7137 7138 7139 7140 7141 7142 |
# File 'array.c', line 7106
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(count) ⇒ Object
Removes and returns trailing elements of self
.
With no argument given, removes and returns the last element, if available; otherwise returns nil
:
a = [:foo, 'bar', 2]
a.pop # => 2
a # => [:foo, "bar"]
[].pop # => nil
With non-negative integer argument count
given, returns a new array containing the trailing count
elements of self
, as available:
a = [:foo, 'bar', 2]
a.pop(2) # => ["bar", 2]
a # => [:foo]
a = [:foo, 'bar', 2]
a.pop(50) # => [:foo, "bar", 2]
a # => []
Related: Array#push; see also Methods for Deleting.
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 |
# File 'array.c', line 1473
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 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.
With no block given, returns the combinations as an array of arrays:
p = [0, 1].product([2, 3])
# => [[0, 2], [0, 3], [1, 2], [1, 3]]
p.size # => 4
p = [0, 1].product([2, 3], [4, 5])
# => [[0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3,...
p.size # => 8
If self
or any argument is empty, returns an empty array:
[].product([2, 3], [4, 5]) # => []
[0, 1].product([2, 3], []) # => []
If no argument is given, returns an array of 1-element arrays, each containing an element of self
:
a.product # => [[0], [1], [2]]
With a block given, calls the block with each combination; returns self
:
p = []
[0, 1].product([2, 3]) {|combination| p.push(combination) }
p # => [[0, 2], [0, 3], [1, 2], [1, 3]]
If self
or any argument is empty, does not call the block:
[].product([2, 3], [4, 5]) {|combination| fail 'Cannot happen' }
# => []
[0, 1].product([2, 3], []) {|combination| fail 'Cannot happen' }
# => [0, 1]
If no argument is given, calls the block with each element of self
as a 1-element array:
p = []
[0, 1].product {|combination| p.push(combination) }
p # => [[0], [1]]
Related: see Methods for Combining.
7532 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 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 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 |
# File 'array.c', line 7532
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 = rb_ary_hidden_new(n);
volatile VALUE t1 = Qundef;
VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */
VALUE result = Qnil; /* The array we'll be returning, when no block given */
long i,j;
long resultlen = 1;
RBASIC_CLEAR_CLASS(t0);
/* initialize the arrays of arrays */
ARY_SET_LEN(t0, n);
arrays[0] = ary;
for (i = 1; i < n; i++) arrays[i] = Qnil;
for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
/* initialize the counters for the arrays */
for (i = 0; i < n; i++) counters[i] = 0;
/* Otherwise, allocate and fill in an array of results */
if (rb_block_given_p()) {
/* Make defensive copies of arrays; exit if any is empty */
for (i = 0; i < n; i++) {
if (RARRAY_LEN(arrays[i]) == 0) goto done;
arrays[i] = ary_make_shared_copy(arrays[i]);
}
}
else {
/* Compute the length of the result array; return [] if any is empty */
for (i = 0; i < n; i++) {
long k = RARRAY_LEN(arrays[i]);
if (k == 0) {
result = rb_ary_new2(0);
goto done;
}
if (MUL_OVERFLOW_LONG_P(resultlen, k))
rb_raise(rb_eRangeError, "too big to product");
resultlen *= k;
}
result = rb_ary_new2(resultlen);
}
for (;;) {
int m;
/* fill in one subarray */
VALUE subarray = rb_ary_new2(n);
for (j = 0; j < n; j++) {
rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
}
/* put it on the result array */
if (NIL_P(result)) {
FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);
rb_yield(subarray);
if (!FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {
rb_raise(rb_eRuntimeError, "product reentered");
}
else {
FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);
}
}
else {
rb_ary_push(result, subarray);
}
/*
* Increment the last counter. If it overflows, reset to 0
* and increment the one before it.
*/
m = n-1;
counters[m]++;
while (counters[m] == RARRAY_LEN(arrays[m])) {
counters[m] = 0;
/* If the first counter overflows, we are done */
if (--m < 0) goto done;
counters[m]++;
}
}
done:
ALLOCV_END(t1);
return NIL_P(result) ? ary : result;
}
|
#push(*objects) ⇒ self #append(*objects) ⇒ self Also known as: append
Appends each argument in objects
to self
; returns self
:
a = [:foo, 'bar', 2] # => [:foo, "bar", 2]
a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat]
Appends each argument as a single element, even if it is another array:
a = [:foo, 'bar', 2] # => [:foo, "bar", 2]
a.push([:baz, :bat], [:bam, :bad]) # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]]
Related: see Methods for Assigning.
1418 1419 1420 1421 1422 |
# File 'array.c', line 1418
static VALUE
rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
{
return rb_ary_cat(ary, argv, argc);
}
|
#rassoc(object) ⇒ nil
Returns the first element ele
in self
such that ele
is an array and ele[1] == object
:
a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]]
a.rassoc(4) # => [2, 4]
a.rassoc(5) # => [4, 5, 6]
Returns nil
if no such element is found.
Related: Array#assoc; see also Methods for Fetching.
5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 |
# File 'array.c', line 5183
VALUE
rb_ary_rassoc(VALUE ary, VALUE value)
{
long i;
VALUE v;
for (i = 0; i < RARRAY_LEN(ary); ++i) {
v = rb_check_array_type(RARRAY_AREF(ary, i));
if (RB_TYPE_P(v, T_ARRAY) &&
RARRAY_LEN(v) > 1 &&
rb_equal(RARRAY_AREF(v, 1), value))
return v;
}
return Qnil;
}
|
#reject {|element| ... } ⇒ Object #reject ⇒ Object
With a block given, 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]
With no block given, returns a new Enumerator.
Related: Methods for Fetching.
4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 |
# File 'array.c', line 4400
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
With a block given, calls the block with each element of self
; 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.
With no block given, returns a new Enumerator.
Related: see Methods for Deleting.
4375 4376 4377 4378 4379 4380 4381 |
# File 'array.c', line 4375
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(size) {|combination| ... } ⇒ self #repeated_combination(size) ⇒ Object
With a block given, calls the block with each repeated combination of length size
of the elements of self
; each combination is an array; returns self
. The order of the combinations is indeterminate.
If a positive integer argument size
is given, calls the block with each size
-tuple repeated combination of the elements of self
. The number of combinations is (size+1)(size+2)/2
.
Examples:
-
size
is 1:c = [] [0, 1, 2].repeated_combination(1) {|combination| c.push(combination) } c # => [[0], [1], [2]]
-
size
is 2:c = [] [0, 1, 2].repeated_combination(2) {|combination| c.push(combination) } c # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]
If size
is zero, calls the block once with an empty array.
If size
is negative, does not call the block:
[0, 1, 2].repeated_combination(-1) {|combination| fail 'Cannot happen' }
With no block given, returns a new Enumerator.
Related: see Methods for Combining.
7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 |
# File 'array.c', line 7444
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(size) {|permutation| ... } ⇒ self #repeated_permutation(size) ⇒ Object
With a block given, calls the block with each repeated permutation of length size
of the elements of self
; each permutation is an array; returns self
. The order of the permutations is indeterminate.
If a positive integer argument size
is given, calls the block with each size
-tuple repeated permutation of the elements of self
. The number of permutations is self.size**size
.
Examples:
-
size
is 1:p = [] [0, 1, 2].repeated_permutation(1) {|permutation| p.push(permutation) } p # => [[0], [1], [2]]
-
size
is 2:p = [] [0, 1, 2].repeated_permutation(2) {|permutation| p.push(permutation) } p # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
If size
is zero, calls the block once with an empty array.
If size
is negative, does not call the block:
[0, 1, 2].repeated_permutation(-1) {|permutation| fail 'Cannot happen' }
With no block given, returns a new Enumerator.
Related: see Methods for Combining.
7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 |
# File 'array.c', line 7338
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;
}
|
#initialize_copy(other_array) ⇒ self #replace(other_array) ⇒ self
Replaces the elements of self
with the elements of other_array
, which must be an array-convertible object; returns self
:
a = ['a', 'b', 'c'] # => ["a", "b", "c"]
a.replace(['d', 'e']) # => ["d", "e"]
Related: see Methods for Assigning.
4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 |
# File 'array.c', line 4673
VALUE
rb_ary_replace(VALUE copy, VALUE orig)
{
rb_ary_modify_check(copy);
orig = to_ary(orig);
if (copy == orig) return copy;
rb_ary_reset(copy);
/* orig has enough space to embed the contents of orig. */
if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
RUBY_ASSERT(ARY_EMBED_P(copy));
ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));
ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig));
}
/* orig is embedded but copy does not have enough space to embed the
* contents of orig. */
else if (ARY_EMBED_P(orig)) {
long len = ARY_EMBED_LEN(orig);
VALUE *ptr = ary_heap_alloc_buffer(len);
FL_UNSET_EMBED(copy);
ARY_SET_PTR(copy, ptr);
ARY_SET_LEN(copy, len);
ARY_SET_CAPA(copy, len);
// No allocation and exception expected that could leave `copy` in a
// bad state from the edits above.
ary_memcpy(copy, 0, len, RARRAY_CONST_PTR(orig));
}
/* Otherwise, orig is on heap and copy does not have enough space to embed
* the contents of orig. */
else {
VALUE shared_root = ary_make_shared(orig);
FL_UNSET_EMBED(copy);
ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
rb_ary_set_shared(copy, shared_root);
}
ary_verify(copy);
return copy;
}
|
#reverse ⇒ Object
Returns a new array containing the elements of self
in reverse order:
[0, 1, 2].reverse # => [2, 1, 0]
Related: see Methods for Combining.
3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 |
# File 'array.c', line 3159
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(ary);
VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;
do *p2-- = *p1++; while (--len > 0);
}
ARY_SET_LEN(dup, RARRAY_LEN(ary));
return dup;
}
|
#reverse! ⇒ self
Reverses the order of the elements of self
; returns self
:
a = [0, 1, 2]
a.reverse! # => [2, 1, 0]
a # => [2, 1, 0]
Related: see Methods for Assigning.
3142 3143 3144 3145 3146 |
# File 'array.c', line 3142
static VALUE
rb_ary_reverse_bang(VALUE ary)
{
return rb_ary_reverse(ary);
}
|
#reverse_each {|element| ... } ⇒ self #reverse_each ⇒ Enumerator
When a block given, iterates backwards over the elements of self
, passing, in reverse order, each element to the block; returns self
:
a = []
[0, 1, 2].reverse_each {|element| a.push(element) }
a # => [2, 1, 0]
Allows the array to be modified during iteration:
a = ['a', 'b', 'c']
a.reverse_each {|element| a.clear if element.start_with?('b') }
a # => []
When no block given, returns a new Enumerator.
Related: see Methods for Iterating.
2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 |
# File 'array.c', line 2716
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
.
With argument object
given, 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.
With a block given, calls the block with each successive element; returns the index of the last element for which the block returns a truthy value:
a = [:foo, 'bar', 2, 'bar']
a.rindex {|element| element == 'bar' } # => 3
Returns nil
if the block never returns a truthy value.
When neither an argument nor a block is given, returns a new Enumerator.
Related: see Methods for Querying.
2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 |
# File 'array.c', line 2157
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(count = 1) ⇒ Object
Returns a new array formed from self
with elements rotated from one end to the other.
With non-negative numeric count
, rotates elements from the beginning to the end:
[0, 1, 2, 3].rotate(2) # => [2, 3, 0, 1]
[0, 1, 2, 3].rotate(2.1) # => [2, 3, 0, 1]
If count
is large, uses count % array.size
as the count:
[0, 1, 2, 3].rotate(22) # => [2, 3, 0, 1]
With a count
of zero, rotates no elements:
[0, 1, 2, 3].rotate(0) # => [0, 1, 2, 3]
With negative numeric count
, rotates in the opposite direction, from the end to the beginning:
[0, 1, 2, 3].rotate(-1) # => [3, 0, 1, 2]
If count
is small (far from zero), uses count % array.size
as the count:
[0, 1, 2, 3].rotate(-21) # => [3, 0, 1, 2]
Related: see Methods for Fetching.
3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 |
# File 'array.c', line 3289
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(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!(count = 1) ⇒ self
Rotates self
in place by moving elements from one end to the other; returns self
.
With non-negative numeric count
, rotates count
elements from the beginning to the end:
[0, 1, 2, 3].rotate!(2) # => [2, 3, 0, 1]
[0, 1, 2, 3].rotate!(2.1) # => [2, 3, 0, 1]
If count
is large, uses count % array.size
as the count:
[0, 1, 2, 3].rotate!(21) # => [1, 2, 3, 0]
If count
is zero, rotates no elements:
[0, 1, 2, 3].rotate!(0) # => [0, 1, 2, 3]
With a negative numeric count
, rotates in the opposite direction, from end to beginning:
[0, 1, 2, 3].rotate!(-1) # => [3, 0, 1, 2]
If count
is small (far from zero), uses count % array.size
as the count:
[0, 1, 2, 3].rotate!(-21) # => [3, 0, 1, 2]
Related: see Methods for Assigning.
3248 3249 3250 3251 3252 3253 3254 |
# File 'array.c', line 3248
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 #filter {|element| ... } ⇒ Object #filter ⇒ Object
With a block given, calls the block 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]
a.select {|element| element.to_s.start_with?('b') }
# => ["bar", :bam]
With no block given, returns a new Enumerator.
Related: see Methods for Fetching.
3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 |
# File 'array.c', line 3877
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 #filter! {|element| ... } ⇒ self? #filter! ⇒ Object
With a block given, calls the block 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.
With no block given, returns a new Enumerator.
Related: see Methods for Deleting.
3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 |
# File 'array.c', line 3960
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(count) ⇒ nil
Removes and returns leading elements from self
.
With no argument, removes and returns one element, if available, or nil
otherwise:
a = [0, 1, 2, 3]
a.shift # => 0
a # => [1, 2, 3]
[].shift # => nil
With non-negative numeric argument count
given, removes and returns the first count
elements:
a = [0, 1, 2, 3]
a.shift(2) # => [0, 1]
a # => [2, 3]
a.shift(1.1) # => [2]
a # => [3]
a.shift(0) # => []
a # => [3]
If count
is large, removes and returns all elements:
a = [0, 1, 2, 3]
a.shift(50) # => [0, 1, 2, 3]
a # => []
If self
is empty, returns a new empty array.
Related: see Methods for Deleting.
1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 |
# File 'array.c', line 1545
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;
}
|
#length ⇒ Integer #size ⇒ Integer
Returns the count of elements in self
:
[0, 1, 2].length # => 3
[].length # => 0
Related: see Methods for Querying.
2747 2748 2749 2750 2751 2752 |
# File 'array.c', line 2747
static VALUE
rb_ary_length(VALUE ary)
{
long len = RARRAY_LEN(ary);
return LONG2NUM(len);
}
|
#[](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
.
In brief:
a = [:foo, 'bar', 2]
# Single argument index: returns one element.
a[0] # => :foo # Zero-based index.
a[-1] # => 2 # Negative index counts backwards from end.
# Arguments start and length: returns an array.
a[1, 2] # => ["bar", 2]
a[-2, 2] # => ["bar", 2] # Negative start counts backwards from end.
# Single argument range: returns an array.
a[0..1] # => [:foo, "bar"]
a[0..-2] # => [:foo, "bar"] # Negative range-begin counts backwards from end.
a[-2..2] # => ["bar", 2] # Negative range-end counts backwards from end.
When a single integer 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 backwards from 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]
Related: see Methods for Fetching.
1888 1889 1890 1891 1892 1893 1894 1895 1896 |
# File 'array.c', line 1888
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!(index) ⇒ Object? #slice!(start, length) ⇒ nil #slice!(range) ⇒ nil
Removes and returns elements from self
.
With numeric argument index
given, removes and returns the element at offset index
:
a = ['a', 'b', 'c', 'd']
a.slice!(2) # => "c"
a # => ["a", "b", "d"]
a.slice!(2.1) # => "d"
a # => ["a", "b"]
If index
is negative, counts backwards from the end of self
:
a = ['a', 'b', 'c', 'd']
a.slice!(-2) # => "c"
a # => ["a", "b", "d"]
If index
is out of range, returns nil
.
With numeric arguments start
and length
given, removes length
elements from self
beginning at zero-based offset start
; returns the removed objects in a new array:
a = ['a', 'b', 'c', 'd']
a.slice!(1, 2) # => ["b", "c"]
a # => ["a", "d"]
a.slice!(0.1, 1.1) # => ["a"]
a # => ["d"]
If start
is negative, counts backwards from the end of self
:
a = ['a', 'b', 'c', 'd']
a.slice!(-2, 1) # => ["c"]
a # => ["a", "b", "d"]
If start
is out-of-range, returns nil
:
a = ['a', 'b', 'c', 'd']
a.slice!(5, 1) # => nil
a.slice!(-5, 1) # => nil
If start + length
exceeds the array size, removes and returns all elements from offset start
to the end:
a = ['a', 'b', 'c', 'd']
a.slice!(2, 50) # => ["c", "d"]
a # => ["a", "b"]
If start == a.size
and length
is non-negative, returns a new empty array.
If length
is negative, returns nil
.
With Range argument range
given, treats range.min
as start
(as above) and range.size
as length
(as above):
a = ['a', 'b', 'c', 'd']
a.slice!(1..2) # => ["b", "c"]
a # => ["a", "d"]
If range.start == a.size
, returns a new empty array:
a = ['a', 'b', 'c', 'd']
a.slice!(4..5) # => []
If range.start
is larger than the array size, returns nil
:
a = ['a', 'b', 'c', 'd']
a.slice!(5..6) # => nil
If range.start
is negative, calculates the start index by counting backwards from the end of self
:
a = ['a', 'b', 'c', 'd']
a.slice!(-2..2) # => ["c"]
If range.end
is negative, calculates the end index by counting backwards from the end of self
:
a = ['a', 'b', 'c', 'd']
a.slice!(0..-2) # => ["a", "b", "c"]
Related: see Methods for Deleting.
4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 |
# File 'array.c', line 4279
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 containing the elements of self
, sorted.
With no block given, compares elements using operator #<=>
(see Object#<=>):
[0, 2, 3, 1].sort # => [0, 1, 2, 3]
With a block given, calls the block with each combination of pairs of elements from self
; for each pair a
and b
, the block should return a numeric:
-
Negative when
b
is to followa
. -
Zero when
a
andb
are equivalent. -
Positive when
a
is to followb
.
Example:
a = [3, 2, 0, 1]
a.sort {|a, b| a <=> b } # => [0, 1, 2, 3]
a.sort {|a, b| b <=> a } # => [3, 2, 1, 0]
When the block returns zero, the order for a
and b
is indeterminate, and may be unstable.
Related: see Methods for Fetching.
3480 3481 3482 3483 3484 3485 3486 |
# File 'array.c', line 3480
VALUE
rb_ary_sort(VALUE ary)
{
ary = rb_ary_dup(ary);
rb_ary_sort_bang(ary);
return ary;
}
|
#sort! ⇒ self #sort! {|a, b| ... } ⇒ self
Like Array#sort, but returns self
with its elements sorted in place.
Related: see Methods for Assigning.
3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 |
# File 'array.c', line 3387
VALUE
rb_ary_sort_bang(VALUE ary)
{
rb_ary_modify(ary);
RUBY_ASSERT(!ARY_SHARED_P(ary));
if (RARRAY_LEN(ary) > 1) {
VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
struct ary_sort_data data;
long len = RARRAY_LEN(ary);
RBASIC_CLEAR_CLASS(tmp);
data.ary = tmp;
data.receiver = ary;
RARRAY_PTR_USE(tmp, ptr, {
ruby_qsort(ptr, len, sizeof(VALUE),
rb_block_given_p()?sort_1:sort_2, &data);
}); /* WB: no new reference */
rb_ary_modify(ary);
if (ARY_EMBED_P(tmp)) {
if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
}
if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) {
ary_resize_capa(ary, ARY_EMBED_LEN(tmp));
}
ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
}
else {
if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
FL_UNSET_SHARED(ary);
ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
}
else {
RUBY_ASSERT(!ARY_SHARED_P(tmp));
if (ARY_EMBED_P(ary)) {
FL_UNSET_EMBED(ary);
}
else if (ARY_SHARED_P(ary)) {
/* ary might be destructively operated in the given block */
rb_ary_unshare(ary);
}
else {
ary_heap_free(ary);
}
ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
ARY_SET_HEAP_LEN(ary, len);
ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
}
/* tmp was lost ownership for the ptr */
FL_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
With a block given, sorts the elements of self
in place; returns self.
Calls the block with each successive element; sorts elements based on the values returned from the block:
a = ['aaaa', 'bbb', 'cc', 'd']
a.sort_by! {|element| element.size }
a # => ["d", "cc", "bbb", "aaaa"]
For duplicate values returned by the block, the ordering is indeterminate, and may be unstable.
With no block given, returns a new Enumerator.
Related: see Methods for Assigning.
3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 |
# File 'array.c', line 3603
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
With no block given, returns the sum of init
and all elements of self
;
for array +array+ and value +init+, equivalent to:
sum = init
array.each {|element| sum += element }
sum
For example, <tt>[e0, e1, e2].sum</tt> returns <tt>init + e0 + e1 + e2</tt>.
Examples:
[0, 1, 2, 3].sum # => 6
[0, 1, 2, 3].sum(100) # => 106
['abc', 'def', 'ghi'].sum('jkl') # => "jklabcdefghi"
[[:foo, :bar], ['foo', 'bar']].sum([2, 3])
# => [2, 3, :foo, :bar, "foo", "bar"]
The +init+ value and elements need not be numeric, but must all be <tt>+</tt>-compatible:
# Raises TypeError: Array can't be coerced into Integer.
[[:foo, :bar], ['foo', 'bar']].sum(2)
With a block given, calls the block with each element of +self+;
the block's return value (instead of the element itself) is used as the addend:
['zero', 1, :two].sum('Coerced and concatenated: ') {|element| element.to_s }
# => "Coerced and concatenated: zero1two"
Notes:
- 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#+.
8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 |
# File 'array.c', line 8098
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;
if (!FIXNUM_P(v) && !RB_BIGNUM_TYPE_P(v) && !RB_TYPE_P(v, T_RATIONAL)) {
i = 0;
goto init_is_a_value;
}
for (i = 0; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
if (FIXNUM_P(e)) {
n += FIX2LONG(e); /* should not overflow long type */
if (!FIXABLE(n)) {
v = rb_big_plus(LONG2NUM(n), v);
n = 0;
}
}
else if (RB_BIGNUM_TYPE_P(e))
v = rb_big_plus(e, v);
else if (RB_TYPE_P(e, T_RATIONAL)) {
if (UNDEF_P(r))
r = e;
else
r = rb_rational_plus(r, e);
}
else
goto not_exact;
}
v = finish_exact_sum(n, r, v, argc!=0);
return v;
not_exact:
v = finish_exact_sum(n, r, v, i!=0);
if (RB_FLOAT_TYPE_P(e)) {
/*
* Kahan-Babuska balancing compensated summation algorithm
* See https://link.springer.com/article/10.1007/s00607-005-0139-x
*/
double f, c;
double x, t;
f = NUM2DBL(v);
c = 0.0;
goto has_float_value;
for (; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
if (RB_FLOAT_TYPE_P(e))
has_float_value:
x = RFLOAT_VALUE(e);
else if (FIXNUM_P(e))
x = FIX2LONG(e);
else if (RB_BIGNUM_TYPE_P(e))
x = rb_big2dbl(e);
else if (RB_TYPE_P(e, T_RATIONAL))
x = rb_num2dbl(e);
else
goto not_float;
if (isnan(f)) continue;
if (isnan(x)) {
f = x;
continue;
}
if (isinf(x)) {
if (isinf(f) && signbit(x) != signbit(f))
f = NAN;
else
f = x;
continue;
}
if (isinf(f)) continue;
t = f + x;
if (fabs(f) >= fabs(x))
c += ((f - t) + x);
else
c += ((x - t) + f);
f = t;
}
f += c;
return DBL2NUM(f);
not_float:
v = DBL2NUM(f);
}
goto has_some_value;
init_is_a_value:
for (; i < RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (block_given)
e = rb_yield(e);
has_some_value:
v = rb_funcall(v, idPLUS, 1, e);
}
return v;
}
|
#take(count) ⇒ Object
Returns a new array containing the first count
element of self
(as available); count
must be a non-negative numeric; does not modify self
:
a = ['a', 'b', 'c', 'd']
a.take(2) # => ["a", "b"]
a.take(2.1) # => ["a", "b"]
a.take(50) # => ["a", "b", "c", "d"]
a.take(0) # => []
Related: see Methods for Fetching.
7638 7639 7640 7641 7642 7643 7644 7645 7646 |
# File 'array.c', line 7638
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
With a block given, calls the block with each successive element of self
; stops iterating 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.take_while {|element| false } # => []
With no block given, returns a new Enumerator.
Does not modify self
.
Related: see Methods for Fetching.
7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 |
# File 'array.c', line 7669
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
.
Otherwise, returns a new array containing the elements of self
:
class MyArray < Array; end
my_a = MyArray.new(['foo', 'bar', 'two'])
a = my_a.to_a
a # => ["foo", "bar", "two"]
a.class # => Array # Not MyArray.
Related: see Methods for Converting.
3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 |
# File 'array.c', line 3029
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
.
3096 3097 3098 3099 3100 |
# File 'array.c', line 3096
static VALUE
rb_ary_to_ary_m(VALUE ary)
{
return ary;
}
|
#to_h ⇒ Object #to_h {|element| ... } ⇒ Object
Returns a new hash formed from self
.
With no block given, each element of self
must be a 2-element sub-array; forms each sub-array into a key-value pair in the new hash:
a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']]
a.to_h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"}
[].to_h # => {}
With a block given, the block must return a 2-element array; calls the block with each element of self
; forms each returned array into a key-value pair in the returned hash:
a = ['foo', :bar, 1, [2, 3], {baz: 4}]
a.to_h {|element| [element, element.class] }
# => {"foo"=>String, :bar=>Symbol, 1=>Integer, [2, 3]=>Array, {:baz=>4}=>Hash}
Related: see Methods for Converting.
3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 |
# File 'array.c', line 3065
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
Returns a new array that is self
as a transposed matrix:
a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]]
a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
The elements of self
must all be the same size.
Related: see Methods for Converting.
4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 |
# File 'array.c', line 4630
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 the elements of self
and all given arrays other_arrays
; items are compared using eql?
:
[0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7]
Removes duplicates (preserving the first found):
[0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3]
Preserves order (preserving the position of the first found):
[3, 2, 1, 0].union([5, 3], [4, 2]) # => [3, 2, 1, 0, 5, 4]
With no arguments given, returns a copy of self
.
Related: see Methods for Combining.
5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 |
# File 'array.c', line 5802
static VALUE
rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
{
int i;
long sum;
VALUE hash;
sum = RARRAY_LEN(ary);
for (i = 0; i < argc; i++) {
argv[i] = to_ary(argv[i]);
sum += RARRAY_LEN(argv[i]);
}
if (sum <= SMALL_ARRAY_LEN) {
VALUE ary_union = rb_ary_new();
rb_ary_union(ary_union, ary);
for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
return ary_union;
}
hash = ary_make_hash(ary);
for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);
return rb_hash_values(hash);
}
|
#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 duplicate elements using method eql?
to compare elements:
a = [0, 0, 1, 1, 2, 2]
a.uniq # => [0, 1, 2]
With a block given, calls the block for each element; identifies and omits “duplicate” elements using method eql?
to compare block return values; that is, an element is a duplicate if its block return value is the same as that of a previous element:
a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq {|element| element.size } # => ["a", "aa", "aaa"]
Related: Methods for Fetching.
6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 |
# File 'array.c', line 6359
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);
}
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 elements:
a = [0, 0, 1, 1, 2, 2]
a.uniq! # => [0, 1, 2]
a.uniq! # => nil
With a block given, calls the block for each element; identifies and omits “duplicate” elements using method eql?
to compare block return values; that is, an element is a duplicate if its block return value is the same as that of a previous element:
a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq! {|element| element.size } # => ["a", "aa", "aaa"]
a.uniq! {|element| element.size } # => nil
Related: see Methods for Deleting.
6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 |
# File 'array.c', line 6303
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)) {
rb_ary_unshare(ary);
FL_SET_EMBED(ary);
}
ary_resize_capa(ary, hash_size);
rb_hash_foreach(hash, push_value, ary);
return ary;
}
|
#unshift(*objects) ⇒ self #prepend(*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]
Related: Array#shift; see also Methods for Assigning.
1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 |
# File 'array.c', line 1695
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(*specifiers) ⇒ Object
Returns elements from self
in a new array; does not modify self
.
The objects included in the returned array are the elements of self
selected by the given specifiers
, each of which must be a numeric index or a Range.
In brief:
a = ['a', 'b', 'c', 'd']
# Index specifiers.
a.values_at(2, 0, 2, 0) # => ["c", "a", "c", "a"] # May repeat.
a.values_at(-4, -3, -2, -1) # => ["a", "b", "c", "d"] # Counts backwards if negative.
a.values_at(-50, 50) # => [nil, nil] # Outside of self.
# Range specifiers.
a.values_at(1..3) # => ["b", "c", "d"] # From range.begin to range.end.
a.values_at(1...3) # => ["b", "c"] # End excluded.
a.values_at(3..1) # => [] # No such elements.
a.values_at(-3..3) # => ["b", "c", "d"] # Negative range.begin counts backwards.
a.values_at(-50..3) # Raises RangeError.
a.values_at(1..-2) # => ["b", "c"] # Negative range.end counts backwards.
a.values_at(1..-50) # => [] # No such elements.
# Mixture of specifiers.
a.values_at(2..3, 3, 0..1, 0) # => ["c", "d", "d", "a", "b", "a"]
With no specifiers
given, returns a new empty array:
a = ['a', 'b', 'c', 'd']
a.values_at # => []
For each numeric specifier index
, includes an element:
-
For each non-negative numeric specifier
index
that is in-range (less thanself.size
), includes the element at offsetindex
:a.values_at(0, 2) # => ["a", "c"] a.values_at(0.1, 2.9) # => ["a", "c"]
-
For each negative numeric
index
that is in-range (greater than or equal to- self.size
), counts backwards from the end ofself
:a.values_at(-1, -4) # => ["d", "a"]
The given indexes may be in any order, and may repeat:
a.values_at(2, 0, 1, 0, 2) # => ["c", "a", "b", "a", "c"]
For each index
that is out-of-range, includes nil
:
a.values_at(4, -5) # => [nil, nil]
For each Range specifier range
, includes elements according to range.begin
and range.end
:
-
If both
range.begin
andrange.end
are non-negative and in-range (less thanself.size
), includes elements from indexrange.begin
throughrange.end - 1
(ifrange.exclude_end?
), or throughrange.end
(otherwise):a.values_at(1..2) # => ["b", "c"] a.values_at(1...2) # => ["b"]
-
If
range.begin
is negative and in-range (greater than or equal to- self.size
), counts backwards from the end ofself
:a.values_at(-2..3) # => ["c", "d"]
-
If
range.begin
is negative and out-of-range, raises an exception:a.values_at(-5..3) # Raises RangeError.
-
If
range.end
is positive and out-of-range, extends the returned array withnil
elements:a.values_at(1..5) # => ["b", "c", "d", nil, nil]
-
If
range.end
is negative and in-range, counts backwards from the end ofself
:a.values_at(1..-2) # => ["b", "c"]
-
If
range.end
is negative and out-of-range, returns an empty array:a.values_at(1..-5) # => []
The given ranges may be in any order and may repeat:
a.values_at(2..3, 0..1, 2..3) # => ["c", "d", "a", "b", "c", "d"]
The given specifiers may be any mixture of indexes and ranges:
a.values_at(3, 1..2, 0, 2..3) # => ["d", "b", "c", "a", "c", "d"]
Related: see Methods for Fetching.
3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 |
# File 'array.c', line 3844
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) {|sub_array| ... } ⇒ nil
With no block given, combines self
with the collection of other_arrays
; returns a new array of sub-arrays:
[0, 1].zip(['zero', 'one'], [:zero, :one])
# => [[0, "zero", :zero], [1, "one", :one]]
Returned:
-
The outer array is of size
self.size
. -
Each sub-array is of size
other_arrays.size + 1
. -
The nth sub-array contains (in order):
-
The nth element of
self
. -
The nth element of each of the other arrays, as available.
-
Example:
a = [0, 1]
zipped = a.zip(['zero', 'one'], [:zero, :one])
# => [[0, "zero", :zero], [1, "one", :one]]
zipped.size # => 2 # Same size as a.
zipped.first.size # => 3 # Size of other arrays plus 1.
When the other arrays are all the same size as self
, the returned sub-arrays are a rearrangement containing exactly elements of all the arrays (including self
), with no omissions or additions:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
d = a.zip(b, c)
pp d
# =>
[[:a0, :b0, :c0],
[:a1, :b1, :c1],
[:a2, :b2, :c2],
[:a3, :b3, :c3]]
When one of the other arrays is smaller than self
, pads the corresponding sub-array with nil
elements:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2]
c = [:c0, :c1]
d = a.zip(b, c)
pp d
# =>
[[:a0, :b0, :c0],
[:a1, :b1, :c1],
[:a2, :b2, nil],
[:a3, nil, nil]]
When one of the other arrays is larger than self
, ignores its trailing elements:
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3, :b4]
c = [:c0, :c1, :c2, :c3, :c4, :c5]
d = a.zip(b, c)
pp d
# =>
[[:a0, :b0, :c0],
[:a1, :b1, :c1],
[:a2, :b2, :c2],
[:a3, :b3, :c3]]
With a block given, calls the block with each of the other arrays; returns nil
:
d = []
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
a.zip(b, c) {|sub_array| d.push(sub_array.reverse) } # => nil
pp d
# =>
[[:c0, :b0, :a0],
[:c1, :b1, :a1],
[:c2, :b2, :a2],
[:c3, :b3, :a3]]
For an object in other_arrays that is not actually an array, forms the the “other array” as object.to_ary
, if defined, or as object.each.to_a
otherwise.
Related: see Methods for Converting.
4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 |
# File 'array.c', line 4557
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 self
and 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: see Methods for Combining.
5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 |
# File 'array.c', line 5760
static VALUE
rb_ary_or(VALUE ary1, VALUE ary2)
{
VALUE hash;
ary2 = to_ary(ary2);
if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
VALUE ary3 = rb_ary_new();
rb_ary_union(ary3, ary1);
rb_ary_union(ary3, ary2);
return ary3;
}
hash = ary_make_hash(ary1);
rb_ary_union_hash(hash, ary2);
return rb_hash_values(hash);
}
|