# class Array

### Public Class Methods

wrap(object) click to toggle source

Wraps its argument in an array unless it is already an array (or array-like).

Specifically:

- If the argument is `nil` an empty list 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.

  ::wrap # => [] ::wrap([1, 2, 3]) # => [1, 2, 3] ::wrap # => [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 such a `nil` 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, though special-cases `nil` to return an empty array.

The last point is particularly worth comparing for some enumerables:

    Array(:foo => :bar)      # => [[:foo, :bar]]
    Array.wrap(:foo => :bar) # => [{:foo => :bar}]

    Array("foo\nbar")        # => ["foo\n", "bar"], in Ruby 1.8
    Array.wrap("foo\nbar")   # => ["foo\nbar"]

There’s also a related idiom that uses the splat operator:

    [*object]

which returns `[nil]` for `nil`, and calls to `Array(object)` otherwise.

Thus, in this case the behavior is different for `nil`, and the differences with `Kernel#Array` explained above apply to the rest of +object+s.

    # File 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

### Public Instance Methods

extract_options!() click to toggle source

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}

    # File lib/active_support/core_ext/array/extract_options.rb, line 22
    def extract_options!
      if last.is_a?(Hash) && last.extractable_options?
        pop
      else
        {}
      end
    end

fifth() click to toggle source

Equal to `self[4]`.

    # File lib/active_support/core_ext/array/access.rb, line 38
    def fifth
      self[4]
    end

forty_two() click to toggle source

Equal to `self[41]`. Also known as accessing “the reddit”.

    # File lib/active_support/core_ext/array/access.rb, line 43
    def forty_two
      self[41]
    end

fourth() click to toggle source

Equal to `self[3]`.

    # File lib/active_support/core_ext/array/access.rb, line 33
    def fourth
      self[3]
    end

from(position) click to toggle source

Returns the tail of the array from `position`.

    %w( a b c d ).from(0)  # => %w( a b c d )
    %w( a b c d ).from(2)  # => %w( c d )
    %w( a b c d ).from(10) # => %w()
    %w().from(0)           # => %w()

    # File lib/active_support/core_ext/array/access.rb, line 8
    def from(position)
      self[position, length] || []
    end

in_groups(number, fill_with = nil) { |g| ... } click to toggle source

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

    %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
    ["1", "2", "3"]
    ["4", "5"]
    ["6", "7"]

    # File lib/active_support/core_ext/array/grouping.rb, line 56
    def in_groups(number, fill_with = nil)
      # size / 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 / 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)
        padding = fill_with != false &&
          modulo > 0 && length == division ? 1 : 0
        groups << slice(start, length).concat([fill_with] * padding)
        start += length
      end

      if block_given?
        groups.each { |g| yield(g) }
      else
        groups
      end
    end

in_groups_of(number, fill_with = nil) { |slice| ... } click to toggle source

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).in_groups_of(3) {|group| p group}
    ["1", "2", "3"]
    ["4", "5", "6"]
    ["7", nil, nil]

    %w(1 2 3).in_groups_of(2, '&nbsp;') {|group| p group}
    ["1", "2"]
    ["3", "&nbsp;"]

    %w(1 2 3).in_groups_of(2, false) {|group| p group}
    ["1", "2"]
    ["3"]

    # File lib/active_support/core_ext/array/grouping.rb, line 19
    def in_groups_of(number, fill_with = nil)
      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([fill_with] * padding)
      end

      if block_given?
        collection.each_slice(number) { |slice| yield(slice) }
      else
        groups = []
        collection.each_slice(number) { |group| groups << group }
        groups
      end
    end

sample(n=nil) click to toggle source

Backport of #sample based on Marc-Andre Lafortune’s github.com/marcandre/backports/ Returns a random element or `n` random elements from the array. If the array is empty and `n` is nil, returns `nil`. If `n` is passed and its value is less than 0, it raises an `ArgumentError` exception. If the value of `n` is equal or greater than 0 it returns `[]`.

    [1,2,3,4,5,6].sample     # => 4
    [1,2,3,4,5,6].sample(3)  # => [2, 4, 5]
    [1,2,3,4,5,6].sample(-3) # => ArgumentError: negative array size
               [].sample     # => nil
               [].sample(3)  # => []

    # File lib/active_support/core_ext/array/random_access.rb, line 13
    def sample(n=nil)
      return self[Kernel.rand(size)] if n.nil?
      n = n.to_int
    rescue Exception => e
      raise TypeError, "Coercion error: #{n.inspect}.to_int => Integer failed:\n(#{e.message})"
    else
      raise TypeError, "Coercion error: obj.to_int did NOT return an Integer (was #{n.class})" unless n.kind_of? Integer
      raise ArgumentError, "negative array size" if n < 0
      n = size if n > size
      result = Array.new(self)
      n.times do |i|
        r = i + Kernel.rand(size - i)
        result[i], result[r] = result[r], result[i]
      end
      result[n..size] = []
      result
    end

second() click to toggle source

Equal to `self[1]`.

    # File lib/active_support/core_ext/array/access.rb, line 23
    def second
      self[1]
    end

split(value = nil) { |element| ... } click to toggle source

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 lib/active_support/core_ext/array/grouping.rb, line 87
    def split(value = nil)
      using_block = block_given?

      inject([[]]) do |results, element|
        if (using_block && yield(element)) || (value == element)
          results << []
        else
          results.last << element
        end

        results
      end
    end

third() click to toggle source

Equal to `self[2]`.

    # File lib/active_support/core_ext/array/access.rb, line 28
    def third
      self[2]
    end

to(position) click to toggle source

Returns the beginning of the array up to `position`.

    %w( a b c d ).to(0)  # => %w( a )
    %w( a b c d ).to(2)  # => %w( a b c )
    %w( a b c d ).to(10) # => %w( a b c d )
    %w().to(0)           # => %w()

    # File lib/active_support/core_ext/array/access.rb, line 18
    def to(position)
      self.first position + 1
    end

to_default_s(format = :default) click to toggle source
Alias for: to_s
to_formatted_s(format = :default) click to toggle source

Converts a collection of elements into a formatted string by calling `to_s` on all elements and joining them:

    Blog.all.to_formatted_s # => "First PostSecond PostThird Post"

Adding in the `:db` argument as the format yields a comma separated id list:

    Blog.all.to_formatted_s(:db) # => "1,2,3"

    # File lib/active_support/core_ext/array/conversions.rb, line 46
    def to_formatted_s(format = :default)
      case format
        when :db
          if respond_to?(:empty?) && self.empty?
            "null"
          else
            collect { |element| element.id }.join(",")
          end
        else
          to_default_s
      end
    end

Also aliased as: to_s
to_param() click to toggle source

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

    # File lib/active_support/core_ext/object/to_param.rb, line 29
    def to_param
      collect { |e| e.to_param }.join '/'
    end

to_query(key) click to toggle source

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 lib/active_support/core_ext/object/to_query.rb, line 19
    def to_query(key)
      prefix = "#{key}[]"
      collect { |value| value.to_query(prefix) }.join '&'
    end

to_s(format = :default) click to toggle source
Also aliased as: to_default_s
Alias for: to_formatted_s
to_sentence(options = {}) click to toggle source

Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:

- `:words_connector` - The sign or word used to join the elements in arrays with two or more elements (default: “, ”)

- `:two_words_connector` - The sign or word used to join the elements in arrays with two elements (default: “ and ”)

- `:last_word_connector` - The sign or word used to join the last element in arrays with three or more elements (default: “, and ”)

    # File lib/active_support/core_ext/array/conversions.rb, line 11
    def to_sentence(options = {})
      if defined?(I18n)
        default_words_connector     = I18n.translate(:'support.array.words_connector',     :locale => options[:locale])
        default_two_words_connector = I18n.translate(:'support.array.two_words_connector', :locale => options[:locale])
        default_last_word_connector = I18n.translate(:'support.array.last_word_connector', :locale => options[:locale])
      else
        default_words_connector     = ", "
        default_two_words_connector = " and "
        default_last_word_connector = ", and "
      end

      options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
      options.reverse_merge! :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector

      case length
        when 0
          ""
        when 1
          self[0].to_s.dup
        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

to_xml(options = {}) { |builder| ... } click to toggle source

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 “records”:

    [{:foo => 1, :bar => 2}, {:baz => 3}].to_xml

    <xxml version="1.0" encoding="UTF-8"?>
    <records type="array">
      <record>
        <bar type="integer">2<%rbar>
        <foo type="integer">1</foo>
      <%rrecord>
      <record>
        <baz type="integer">3</baz>
      <%rrecord>
    </records>

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")

    <xxml 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)

    <xxml version="1.0" encoding="UTF-8"?>
    <messages>
      <message>
        <created-at>2008-03-07T09:58:18+01:00<%rcreated-at>
        <id>1</d>
        <name>1<%rname>
        <updated-at>2008-03-07T09:58:18+01:00</pdated-at>
        <user-id>1<%ruser-id>
      </essage>
    <%rmessages>

    # File lib/active_support/core_ext/array/conversions.rb, line 136
    def to_xml(options = {})
      require 'active_support/builder' unless defined?(Builder)

      options = options.dup
      options[:indent]  ||= 2
      options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
      options[:root]    ||= if first.class.to_s != "Hash" && all? { |e| e.is_a?(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"}
      return builder.tag!(root, attributes) if empty?

      builder.__send__(:method_missing, root, attributes) do
        each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
        yield builder if block_given?
      end
    end

uniq_by() { |i| ... } click to toggle source

Returns an unique array based on the criteria given as a `Proc`.

    [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]

    # File lib/active_support/core_ext/array/uniq_by.rb, line 6
    def uniq_by
      hash, array = {}, []
      each { |i| hash[yield(i)] ||= (array << i) }
      array
    end

uniq_by!() { |i| ... } click to toggle source

Same as #uniq_by, but modifies self.

    # File lib/active_support/core_ext/array/uniq_by.rb, line 13
    def uniq_by!
      replace(uniq_by{ |i| yield(i) })
    end