Methods

Class Public methods

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 try to_a if the returned value is nil, but Array.wrap returns an array with the argument as its single element right away.

  • If the returned value from to_ary is neither nil nor an Array object, Kernel#Array raises an exception, while Array.wrap does not, it just returns the value.

  • It does not call to_a on the argument, if the argument does not respond to to_ary it returns an array with the argument as its single element.

The last point is easily explained with some enumerables:

Array(foo: :bar)      # => [[:foo, :bar]]
Array.wrap(foo: :bar) # => [{: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 objects.

πŸ“ Source code
# 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
πŸ”Ž See on GitHub

Instance Public methods

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
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 29
  def deep_dup
    map(&:deep_dup)
  end
πŸ”Ž See on GitHub

excluding(*elements)

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.

Also aliased as: without
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 47
  def excluding(*elements)
    self - elements.flatten(1)
  end
πŸ”Ž See on GitHub

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]
πŸ“ Source code
# 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
πŸ”Ž See on GitHub

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 options(*args)
  args.extract_options!
end

options(1, 2)        # => {}
options(1, 2, a: :b) # => {:a=>:b}
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/extract_options.rb, line 24
  def extract_options!
    if last.is_a?(Hash) && last.extractable_options?
      pop
    else
      {}
    end
  end
πŸ”Ž See on GitHub

fifth()

Equal to self[4].

%w( a b c d e ).fifth # => "e"
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 76
  def fifth
    self[4]
  end
πŸ”Ž See on GitHub

forty_two()

Equal to self[41]. Also known as accessing β€œthe reddit”.

(1..42).to_a.forty_two # => 42
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 83
  def forty_two
    self[41]
  end
πŸ”Ž See on GitHub

fourth()

Equal to self[3].

%w( a b c d e ).fourth # => "d"
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 69
  def fourth
    self[3]
  end
πŸ”Ž See on GitHub

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)  # => []
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 12
  def from(position)
    self[position, length] || []
  end
πŸ”Ž See on GitHub

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, '&nbsp;') {|group| p group}
["1", "2", "3", "4"]
["5", "6", "7", "&nbsp;"]
["8", "9", "10", "&nbsp;"]

%w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
["1", "2", "3"]
["4", "5"]
["6", "7"]
πŸ“ Source code
# 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
πŸ”Ž See on GitHub

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, '&nbsp;') {|group| p group}
["1", "2"]
["3", "4"]
["5", "&nbsp;"]

%w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
["1", "2"]
["3", "4"]
["5"]
πŸ“ Source code
# 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
πŸ”Ž See on GitHub

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 ] ]
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 36
  def including(*elements)
    self + elements.flatten(1)
  end
πŸ”Ž See on GitHub

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
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/inquiry.rb, line 16
  def inquiry
    ActiveSupport::ArrayInquirer.new(self)
  end
πŸ”Ž See on GitHub

second()

Equal to self[1].

%w( a b c d e ).second # => "b"
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 55
  def second
    self[1]
  end
πŸ”Ž See on GitHub

second_to_last()

Equal to self[-2].

%w( a b c d e ).second_to_last # => "d"
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 97
  def second_to_last
    self[-2]
  end
πŸ”Ž See on GitHub

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]]
πŸ“ Source code
# 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
πŸ”Ž See on GitHub

third()

Equal to self[2].

%w( a b c d e ).third # => "c"
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 62
  def third
    self[2]
  end
πŸ”Ž See on GitHub

third_to_last()

Equal to self[-3].

%w( a b c d e ).third_to_last # => "c"
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/access.rb, line 90
  def third_to_last
    self[-3]
  end
πŸ”Ž See on GitHub

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)  # => []
πŸ“ Source code
# 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
πŸ”Ž See on GitHub

to_formatted_s(format = :default)

Alias for: to_fs

to_fs(format = :default)

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]"
Also aliased as: to_formatted_s
πŸ“ Source code
# 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
πŸ”Ž See on GitHub

to_param()

Calls to_param on all its elements and joins the result with slashes. This is used by url_for in Action Pack.

πŸ“ Source code
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 42
  def to_param
    collect(&:to_param).join "/"
  end
πŸ”Ž See on GitHub

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"
πŸ“ Source code
# 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
πŸ”Ž See on GitHub

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 - If i18n 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"
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 60
  def to_sentence(options = {})
    options.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 options[:locale] != false && defined?(I18n)
      i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
      default_connectors.merge!(i18n_connectors)
    end
    options = default_connectors.merge!(options)

    case length
    when 0
      +""
    when 1
      +"#{self[0]}"
    when 2
      +"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
    else
      +"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
    end
  end
πŸ”Ž See on GitHub

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>
    <bar 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"?>
<messages>
  <message>
    <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>
πŸ“ Source code
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 183
  def to_xml(options = {})
    require "active_support/builder" unless defined?(Builder::XmlMarkup)

    options = options.dup
    options[:indent]  ||= 2
    options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
    options[:root]    ||= \
      if first.class != Hash && all?(first.class)
        underscored = ActiveSupport::Inflector.underscore(first.class.name)
        ActiveSupport::Inflector.pluralize(underscored).tr("/", "_")
      else
        "objects"
      end

    builder = options[:builder]
    builder.instruct! unless options.delete(:skip_instruct)

    root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
    children = options.delete(:children) || root.singularize
    attributes = options[:skip_types] ? {} : { type: "array" }

    if empty?
      builder.tag!(root, attributes)
    else
      builder.tag!(root, attributes) do
        each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
        yield builder if block_given?
      end
    end
  end
πŸ”Ž See on GitHub

without(*elements)

Alias for: excluding