Class: Array
Class Method Summary
-
.wrap(object)
Wraps its argument in an array unless it is already an array (or array-like).
Instance Attribute Summary
- #present? ⇒ Boolean readonly Internal use only
Instance Method Summary
-
#blank? ⇒ true, false
An array is blank if it’s empty:
-
#deep_dup
Returns a deep copy of array.
-
#excluding(*elements)
(also: #without)
Returns a copy of the
Array
excluding the specified elements. -
#extract!
Removes and returns the elements for which the block returns a true value.
-
#extract_options!
Extracts options from a set of arguments.
-
#fifth
Equal to
self[4]
. -
#forty_two
Equal to
self[41]
. -
#fourth
Equal to
self[3]
. -
#from(position)
Returns the tail of the array from
position
. -
#in_groups(number, fill_with = nil, &block)
Splits or iterates over the array in
number
of groups, padding any remaining slots withfill_with
unless it isfalse
. -
#in_groups_of(number, fill_with = nil, &block)
Splits or iterates over the array in groups of size
number
, padding any remaining slots withfill_with
unless it isfalse
. -
#including(*elements)
Returns a new array that includes the passed elements.
-
#inquiry
Wraps the array in an
::ActiveSupport::ArrayInquirer
object, which gives a friendlier way to check its string-like contents. -
#second
Equal to
self[1]
. -
#second_to_last
Equal to
self[-2]
. -
#split(value = nil, &block)
Divides the array into one or more subarrays based on a delimiting
value
or the result of an optional block. -
#third
Equal to
self[2]
. -
#third_to_last
Equal to
self[-3]
. -
#to(position)
Returns the beginning of the array up to
position
. -
#to_formatted_s(format = :default)
Alias for #to_fs.
-
#to_fs(format = :default)
(also: #to_formatted_s)
Extends
Array#to_s
to convert a collection of elements into a comma separated id list if:db
argument is given as the format. -
#to_param
Calls
to_param
on all its elements and joins the result with slashes. -
#to_query(key)
Converts an array into a string suitable for use as a URL query string, using the given
key
as the param name. -
#to_sentence(options = {})
Converts the array to a comma-separated sentence where the last element is joined by the connector word.
-
#to_xml(options = {})
Returns a string that represents the array in XML by invoking #to_xml on each element.
-
#without(*elements)
Alias for #excluding.
- #as_json(options = nil) Internal use only
-
#compact_blank!
Internal use only
Removes all blank elements from the
Array
in place and returns self.
Class Method Details
.wrap(object)
Wraps its argument in an array unless it is already an array (or array-like).
Specifically:
-
If the argument is
nil
an empty array is returned. -
Otherwise, if the argument responds to
to_ary
it is invoked, and its result returned. -
Otherwise, returns an array with the argument as its single element.
Array.wrap(nil) # => [] Array.wrap([1, 2, 3]) # => [1, 2, 3] Array.wrap(0) # => [0]
This method is similar in purpose to Kernel#Array
, but there are some differences:
-
If the argument responds to
to_ary
the method is invoked.Kernel#Array
moves on to tryto_a
if the returned value isnil
, butwrap
returns an array with the argument as its single element right away. -
If the returned value from
to_ary
is neithernil
nor anArray
object,Kernel#Array
raises an exception, whilewrap
does not, it just returns the value. -
It does not call
to_a
on the argument, if the argument does not respond toto_ary
it returns an array with the argument as its single element.
The last point is easily explained with some enumerables:
Array(foo: : ) # => [[:foo, :bar]]
Array.wrap(foo: : ) # => [{:foo=>:bar}]
There’s also a related idiom that uses the splat operator:
[*object]
which returns []
for nil
, but calls to Array(object)
otherwise.
The differences with Kernel#Array
explained above apply to the rest of object
s.
# File 'activesupport/lib/active_support/core_ext/array/wrap.rb', line 39
def self.wrap(object) if object.nil? [] elsif object.respond_to?(:to_ary) object.to_ary || [object] else [object] end end
Instance Attribute Details
#present? ⇒ Boolean
(readonly)
# File 'activesupport/lib/active_support/core_ext/object/blank.rb', line 104
def present? # :nodoc: !empty? end
Instance Method Details
#as_json(options = nil)
# File 'activesupport/lib/active_support/core_ext/object/json.rb', line 164
def as_json( = nil) # :nodoc: if = .dup.freeze unless .frozen? map { |v| v.as_json( ) } else map { |v| v.as_json } end end
#blank? ⇒ true
, false
An array is blank if it’s empty:
[].blank? # => true
[1,2,3].blank? # => false
# File 'activesupport/lib/active_support/core_ext/object/blank.rb', line 102
alias_method :blank?, :empty?
#compact_blank!
Removes all blank elements from the Array
in place and returns self. Uses Object#blank? for determining if an item is blank.
a = [1, "", nil, 2, " ", [], {}, false, true]
a.compact_blank!
# => [1, 2, true]
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 263
def compact_blank! # use delete_if rather than reject! because it always returns self even if nothing changed delete_if(&:blank?) end
#deep_dup
Returns a deep copy of array.
array = [1, [2, 3]]
dup = array.deep_dup
dup[1][2] = 4
array[1][2] # => nil
dup[1][2] # => 4
# File 'activesupport/lib/active_support/core_ext/object/deep_dup.rb', line 29
def deep_dup map(&:deep_dup) end
#excluding(*elements) Also known as: #without
Returns a copy of the Array
excluding the specified elements.
["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
[ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
Note: This is an optimization of Enumerable#excluding that uses Array#-
instead of Array#reject
for performance reasons.
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 47
def excluding(*elements) self - elements.flatten(1) end
#extract!
Removes and returns the elements for which the block returns a true value. If no block is given, an Enumerator is returned instead.
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers # => [0, 2, 4, 6, 8]
# File 'activesupport/lib/active_support/core_ext/array/extract.rb', line 10
def extract! return to_enum(:extract!) { size } unless block_given? extracted_elements = [] reject! do |element| extracted_elements << element if yield(element) end extracted_elements end
#extract_options!
Extracts options from a set of arguments. Removes and returns the last element in the array if it’s a hash, otherwise returns a blank hash.
def (*args)
args.
end
(1, 2) # => {}
(1, 2, a: :b) # => {:a=>:b}
# File 'activesupport/lib/active_support/core_ext/array/extract_options.rb', line 24
def if last.is_a?(Hash) && last. pop else {} end end
#fifth
Equal to self[4]
.
%w( a b c d e ).fifth # => "e"
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 76
def fifth self[4] end
#forty_two
Equal to self[41]
. Also known as accessing “the reddit”.
(1..42).to_a.forty_two # => 42
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 83
def forty_two self[41] end
#fourth
Equal to self[3]
.
%w( a b c d e ).fourth # => "d"
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 69
def fourth self[3] end
#from(position)
Returns the tail of the array from position
.
%w( a b c d ).from(0) # => ["a", "b", "c", "d"]
%w( a b c d ).from(2) # => ["c", "d"]
%w( a b c d ).from(10) # => []
%w().from(0) # => []
%w( a b c d ).from(-2) # => ["c", "d"]
%w( a b c ).from(-10) # => []
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 12
def from(position) self[position, length] || [] end
#in_groups(number, fill_with = nil, &block)
Splits or iterates over the array in number
of groups, padding any remaining slots with fill_with
unless it is false
.
%w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
["1", "2", "3", "4"]
["5", "6", "7", nil]
["8", "9", "10", nil]
%w(1 2 3 4 5 6 7 8 9 10).in_groups(3, ' ') {|group| p group}
["1", "2", "3", "4"]
["5", "6", "7", " "]
["8", "9", "10", " "]
%w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
["1", "2", "3"]
["4", "5"]
["6", "7"]
# File 'activesupport/lib/active_support/core_ext/array/grouping.rb', line 62
def in_groups(number, fill_with = nil, &block) # size.div number gives minor group size; # size % number gives how many objects need extra accommodation; # each group hold either division or division + 1 items. division = size.div number modulo = size % number # create a new array avoiding dup groups = [] start = 0 number.times do |index| length = division + (modulo > 0 && modulo > index ? 1 : 0) groups << last_group = slice(start, length) last_group << fill_with if fill_with != false && modulo > 0 && length == division start += length end if block_given? groups.each(&block) else groups end end
#in_groups_of(number, fill_with = nil, &block)
Splits or iterates over the array in groups of size number
, padding any remaining slots with fill_with
unless it is false
.
%w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
["1", "2", "3"]
["4", "5", "6"]
["7", "8", "9"]
["10", nil, nil]
%w(1 2 3 4 5).in_groups_of(2, ' ') {|group| p group}
["1", "2"]
["3", "4"]
["5", " "]
%w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
["1", "2"]
["3", "4"]
["5"]
# File 'activesupport/lib/active_support/core_ext/array/grouping.rb', line 22
def in_groups_of(number, fill_with = nil, &block) if number.to_i <= 0 raise ArgumentError, "Group size must be a positive integer, was #{number.inspect}" end if fill_with == false collection = self else # size % number gives how many extra we have; # subtracting from number gives how many to add; # modulo number ensures we don't add group of just fill. padding = (number - size % number) % number collection = dup.concat(Array.new(padding, fill_with)) end if block_given? collection.each_slice(number, &block) else collection.each_slice(number).to_a end end
#including(*elements)
Returns a new array that includes the passed elements.
[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
[ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 36
def including(*elements) self + elements.flatten(1) end
#inquiry
Wraps the array in an ::ActiveSupport::ArrayInquirer
object, which gives a friendlier way to check its string-like contents.
pets = [:cat, :dog].inquiry
pets.cat? # => true
pets.ferret? # => false
pets.any?(:cat, :ferret) # => true
pets.any?(:ferret, :alligator) # => false
# File 'activesupport/lib/active_support/core_ext/array/inquiry.rb', line 16
def inquiry ActiveSupport::ArrayInquirer.new(self) end
#second
Equal to self[1]
.
%w( a b c d e ).second # => "b"
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 55
def second self[1] end
#second_to_last
Equal to self[-2]
.
%w( a b c d e ).second_to_last # => "d"
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 97
def second_to_last self[-2] end
#split(value = nil, &block)
Divides the array into one or more subarrays based on a delimiting value
or the result of an optional block.
[1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
(1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
# File 'activesupport/lib/active_support/core_ext/array/grouping.rb', line 93
def split(value = nil, &block) arr = dup result = [] if block_given? while (idx = arr.index(&block)) result << arr.shift(idx) arr.shift end else while (idx = arr.index(value)) result << arr.shift(idx) arr.shift end end result << arr end
#third
Equal to self[2]
.
%w( a b c d e ).third # => "c"
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 62
def third self[2] end
#third_to_last
Equal to self[-3]
.
%w( a b c d e ).third_to_last # => "c"
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 90
def third_to_last self[-3] end
#to(position)
Returns the beginning of the array up to position
.
%w( a b c d ).to(0) # => ["a"]
%w( a b c d ).to(2) # => ["a", "b", "c"]
%w( a b c d ).to(10) # => ["a", "b", "c", "d"]
%w().to(0) # => []
%w( a b c d ).to(-2) # => ["a", "b", "c"]
%w( a b c ).to(-10) # => []
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 24
def to(position) if position >= 0 take position + 1 else self[0..position] end end
#to_formatted_s(format = :default)
Alias for #to_fs.
# File 'activesupport/lib/active_support/core_ext/array/conversions.rb', line 106
alias_method :to_formatted_s, :to_fs
#to_fs(format = :default) Also known as: #to_formatted_s
Extends Array#to_s
to convert a collection of elements into a comma separated id list if :db
argument is given as the format.
This method is aliased to #to_formatted_s.
Blog.all.to_fs(:db) # => "1,2,3"
Blog.none.to_fs(:db) # => "null"
[1,2].to_fs # => "[1, 2]"
# File 'activesupport/lib/active_support/core_ext/array/conversions.rb', line 94
def to_fs(format = :default) case format when :db if empty? "null" else collect(&:id).join(",") end else to_s end end
#to_param
Calls to_param
on all its elements and joins the result with slashes. This is used by url_for
in Action Pack.
# File 'activesupport/lib/active_support/core_ext/object/to_query.rb', line 42
def to_param collect(&:to_param).join "/" end
#to_query(key)
Converts an array into a string suitable for use as a URL query string, using the given key
as the param name.
['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
# File 'activesupport/lib/active_support/core_ext/object/to_query.rb', line 50
def to_query(key) prefix = "#{key}[]" if empty? nil.to_query(prefix) else collect { |value| value.to_query(prefix) }.join "&" end end
#to_sentence(options = {})
Converts the array to a comma-separated sentence where the last element is joined by the connector word.
You can pass the following options to change the default behavior. If you pass an option key that doesn’t exist in the list below, it will raise an ArgumentError
.
Options
-
:words_connector
- The sign or word used to join all but the last element in arrays with three or more elements (default: “, ”). -
:last_word_connector
- The sign or word used to join the last element in arrays with three or more elements (default: “, and ”). -
:two_words_connector
- The sign or word used to join the elements in arrays with two elements (default: “ and ”). -
:locale
- Ifi18n
is available, you can set a locale and use the connector options defined on the ‘support.array’ namespace in the corresponding dictionary file.
Examples
[].to_sentence # => ""
['one'].to_sentence # => "one"
['one', 'two'].to_sentence # => "one and two"
['one', 'two', 'three'].to_sentence # => "one, two, and three"
['one', 'two'].to_sentence(passing: 'invalid option')
# => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale
['one', 'two'].to_sentence(two_words_connector: '-')
# => "one-two"
['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
# => "one or two or at least three"
Using :locale
option:
# Given this locale dictionary:
#
# es:
# support:
# array:
# words_connector: " o "
# two_words_connector: " y "
# last_word_connector: " o al menos "
['uno', 'dos'].to_sentence(locale: :es)
# => "uno y dos"
['uno', 'dos', 'tres'].to_sentence(locale: :es)
# => "uno o dos o al menos tres"
# File 'activesupport/lib/active_support/core_ext/array/conversions.rb', line 60
def to_sentence( = {}) .assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale) default_connectors = { words_connector: ", ", two_words_connector: " and ", last_word_connector: ", and " } if [:locale] != false && defined?(I18n) i18n_connectors = I18n.translate(:'support.array', locale: [:locale], default: {}) default_connectors.merge!(i18n_connectors) end = default_connectors.merge!( ) case length when 0 +"" when 1 +"#{self[0]}" when 2 +"#{self[0]}#{ [:two_words_connector]}#{self[1]}" else +"#{self[0...-1].join( [:words_connector])}#{ [:last_word_connector]}#{self[-1]}" end end
#to_xml(options = {})
Returns a string that represents the array in XML by invoking to_xml
on each element. Active Record collections delegate their representation in XML to this method.
All elements are expected to respond to to_xml
, if any of them does not then an exception is raised.
The root node reflects the class name of the first element in plural if all elements belong to the same type and that’s not ::Hash
:
customer.projects.to_xml
<?xml version="1.0" encoding="UTF-8"?>
<projects type="array">
<project>
<amount type="decimal">20000.0</amount>
<customer-id type="integer">1567</customer-id>
<deal-date type="date">2008-04-09</deal-date>
#...
</project>
<project>
<amount type="decimal">57230.0</amount>
<customer-id type="integer">1567</customer-id>
<deal-date type="date">2008-04-15</deal-date>
#...
</project>
</projects>
Otherwise the root element is “objects”:
[{ foo: 1, bar: 2}, { baz: 3}].to_xml
<?xml version="1.0" encoding="UTF-8"?>
<objects type="array">
<object>
< type="integer">2</bar>
<foo type="integer">1</foo>
</object>
<object>
<baz type="integer">3</baz>
</object>
</objects>
If the collection is empty the root element is “nil-classes” by default:
[].to_xml
<?xml version="1.0" encoding="UTF-8"?>
<nil-classes type="array"/>
To ensure a meaningful root element use the :root
option:
customer_with_no_projects.projects.to_xml(root: 'projects')
<?xml version="1.0" encoding="UTF-8"?>
<projects type="array"/>
By default name of the node for the children of root is root.singularize
. You can change it with the :children
option.
The options
hash is passed downwards:
Message.all.to_xml(skip_types: true)
<?xml version="1.0" encoding="UTF-8"?>
<>
<>
<created-at>2008-03-07T09:58:18+01:00</created-at>
<id>1</id>
<name>1</name>
<updated-at>2008-03-07T09:58:18+01:00</updated-at>
<user-id>1</user-id>
</message>
</messages>
# File 'activesupport/lib/active_support/core_ext/array/conversions.rb', line 183
def to_xml( = {}) require "active_support/builder" unless defined?(Builder::XmlMarkup) = .dup [:indent] ||= 2 [:builder] ||= Builder::XmlMarkup.new(indent: [:indent]) [:root] ||= \ if first.class != Hash && all?(first.class) underscored = ActiveSupport::Inflector.underscore(first.class.name) ActiveSupport::Inflector.pluralize(underscored).tr("/", "_") else "objects" end builder = [:builder] builder.instruct! unless .delete(:skip_instruct) root = ActiveSupport::XmlMini.rename_key( [:root].to_s, ) children = .delete(:children) || root.singularize attributes = [:skip_types] ? {} : { type: "array" } if empty? builder.tag!(root, attributes) else builder.tag!(root, attributes) do each { |value| ActiveSupport::XmlMini.to_tag(children, value, ) } yield builder if block_given? end end end
#without(*elements)
Alias for #excluding.
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 50
alias :without :excluding