class Array

Experimental RBS support (using type sampling data from the type_fusion project).

# sig/active_support/core_ext/array/access.rbs

class Array
  def self.wrap: (String? object) -> untyped
  def as_json: (?nil options) -> untyped
  def deep_dup: () -> untyped
  def extract!: () -> untyped
  def extract_options!: () -> untyped
end

def self.wrap(object)

Experimental RBS support (using type sampling data from the type_fusion project).

def self.wrap: (String? object) -> untyped

This signature was generated using 3 samples from 1 application.

apply to the rest of objects.
The differences with Kernel#Array explained above

which returns [] for +nil+, but calls to Array(object) otherwise.

[*object]

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

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

The last point is easily explained with some enumerables:

it returns an array with the argument as its single element.
* It does not call +to_a+ on the argument, if the argument does not respond to +to_ary+
raises an exception, while Array.wrap does not, it just returns the value.
* If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, Kernel#Array
an array with the argument as its single element right away.
moves on to try +to_a+ if the returned value is +nil+, but Array.wrap returns
* If the argument responds to +to_ary+ the method is invoked. Kernel#Array

This method is similar in purpose to Kernel#Array, but there are some differences:

Array.wrap(0) # => [0]
Array.wrap([1, 2, 3]) # => [1, 2, 3]
Array.wrap(nil) # => []

* Otherwise, returns an array with the argument as its single element.
* Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
* If the argument is +nil+ an empty array is returned.

Specifically:

Wraps its argument in an array unless it is already an array (or array-like).
def self.wrap(object)
  if object.nil?
    []
  elsif object.respond_to?(:to_ary)
    object.to_ary || [object]
  else
    [object]
  end
end

def as_json(options = nil) # :nodoc:

Experimental RBS support (using type sampling data from the type_fusion project).

def as_json: (?nil options) -> untyped

This signature was generated using 4 samples from 1 application.

:nodoc:
def as_json(options = nil) # :nodoc:
  map { |v| options ? v.as_json(options.dup) : v.as_json }
end

def compact_blank!

# => [1, 2, true]
a.compact_blank!
a = [1, "", nil, 2, " ", [], {}, false, true]

Uses Object#blank? for determining if an item is blank.
Removes all blank elements from the +Array+ in place and returns self.
def compact_blank!
  # use delete_if rather than reject! because it always returns self even if nothing changed
  delete_if(&:blank?)
end

def deep_dup

Experimental RBS support (using type sampling data from the type_fusion project).

def deep_dup: () -> untyped

This signature was generated using 3 samples from 1 application.

dup[1][2] # => 4
array[1][2] # => nil

dup[1][2] = 4
dup = array.deep_dup
array = [1, [2, 3]]

Returns a deep copy of array.
def deep_dup
  map(&:deep_dup)
end

def excluding(*elements)

instead of Array#reject for performance reasons.
Note: This is an optimization of Enumerable#excluding that uses Array#-

[ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]

Returns a copy of the Array excluding the specified elements.
def excluding(*elements)
  self - elements.flatten(1)
end

def extract!

Experimental RBS support (using type sampling data from the type_fusion project).

def extract!: () -> untyped

This signature was generated using 1 sample from 1 application.

numbers # => [0, 2, 4, 6, 8]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

If no block is given, an Enumerator is returned instead.
Removes and returns the elements for which the block returns a true value.
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

def extract_options!

Experimental RBS support (using type sampling data from the type_fusion project).

def extract_options!: () -> untyped

This signature was generated using 3 samples from 1 application.

options(1, 2, a: :b) # => {:a=>:b}
options(1, 2) # => {}

end
args.extract_options!
def options(*args)

element in the array if it's a hash, otherwise returns a blank hash.
Extracts options from a set of arguments. Removes and returns the last
def extract_options!
  if last.is_a?(Hash) && last.extractable_options?
    pop
  else
    {}
  end
end

def fifth

%w( a b c d e ).fifth # => "e"

Equal to self[4].
def fifth
  self[4]
end

def forty_two

(1..42).to_a.forty_two # => 42

Equal to self[41]. Also known as accessing "the reddit".
def forty_two
  self[41]
end

def fourth

%w( a b c d e ).fourth # => "d"

Equal to self[3].
def fourth
  self[3]
end

def from(position)

%w( a b c ).from(-10) # => []
%w( a b c d ).from(-2) # => ["c", "d"]
%w().from(0) # => []
%w( a b c d ).from(10) # => []
%w( a b c d ).from(2) # => ["c", "d"]
%w( a b c d ).from(0) # => ["a", "b", "c", "d"]

Returns the tail of the array from +position+.
def from(position)
  self[position, length] || []
end

def in_groups(number, fill_with = nil, &block)

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

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

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

remaining slots with +fill_with+ unless it is +false+.
Splits or iterates over the array in +number+ of groups, padding any
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

def in_groups_of(number, fill_with = nil, &block)

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

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

["10", nil, nil]
["7", "8", "9"]
["4", "5", "6"]
["1", "2", "3"]
%w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}

padding any remaining slots with +fill_with+ unless it is +false+.
Splits or iterates over the array in groups of size +number+,
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

def including(*elements)

[ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]

Returns a new array that includes the passed elements.
def including(*elements)
  self + elements.flatten(1)
end

def inquiry

pets.any?(:ferret, :alligator) # => false
pets.any?(:cat, :ferret) # => true

pets.ferret? # => false
pets.cat? # => true

pets = [:cat, :dog].inquiry

friendlier way to check its string-like contents.
Wraps the array in an ActiveSupport::ArrayInquirer object, which gives a
def inquiry
  ActiveSupport::ArrayInquirer.new(self)
end

def second

%w( a b c d e ).second # => "b"

Equal to self[1].
def second
  self[1]
end

def second_to_last

%w( a b c d e ).second_to_last # => "d"

Equal to self[-2].
def second_to_last
  self[-2]
end

def split(value = nil, &block)

(1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
[1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]

or the result of an optional block.
Divides the array into one or more subarrays based on a delimiting +value+
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

def sum(init = nil, &block)

:nodoc:
def sum(init = nil, &block)
  if init.is_a?(Numeric) || first.is_a?(Numeric)
    init ||= 0
    orig_sum(init, &block)
  else
    super
  end
end

def third

%w( a b c d e ).third # => "c"

Equal to self[2].
def third
  self[2]
end

def third_to_last

%w( a b c d e ).third_to_last # => "c"

Equal to self[-3].
def third_to_last
  self[-3]
end

def to(position)

%w( a b c ).to(-10) # => []
%w( a b c d ).to(-2) # => ["a", "b", "c"]
%w().to(0) # => []
%w( a b c d ).to(10) # => ["a", "b", "c", "d"]
%w( a b c d ).to(2) # => ["a", "b", "c"]
%w( a b c d ).to(0) # => ["a"]

Returns the beginning of the array up to +position+.
def to(position)
  if position >= 0
    take position + 1
  else
    self[0..position]
  end
end

def to_fs(format = :default)

[1,2].to_fs # => "[1, 2]"
Blog.none.to_fs(:db) # => "null"
Blog.all.to_fs(:db) # => "1,2,3"

This method is aliased to to_formatted_s.

comma separated id list if :db argument is given as the format.
Extends Array#to_s to convert a collection of elements into a
def to_fs(format = :default)
  case format
  when :db
    if empty?
      "null"
    else
      collect(&:id).join(",")
    end
  else
    to_default_s
  end
end

def to_param

slashes. This is used by url_for in Action Pack.
Calls to_param on all its elements and joins the result with
def to_param
  collect(&:to_param).join "/"
end

def to_query(key)

['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"

using the given +key+ as the param name.
Converts an array into a string suitable for use as a URL query string,
def to_query(key)
  prefix = "#{key}[]"
  if empty?
    nil.to_query(prefix)
  else
    collect { |value| value.to_query(prefix) }.join "&"
  end
end

def to_s(format = NOT_SET) # :nodoc:

:nodoc:
:nodoc:
def to_s(format = NOT_SET) # :nodoc:
  case format
  when :db
    ActiveSupport::Deprecation.warn(
      "Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_fs(#{format.inspect}) instead."
    )
    if empty?
      "null"
    else
      collect(&:id).join(",")
    end
  when NOT_SET
    to_default_s
  else
    ActiveSupport::Deprecation.warn(
      "Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_fs(#{format.inspect}) instead."
    )
    to_default_s
  end
end

def to_sentence(options = {})

# => "uno o dos o al menos tres"
['uno', 'dos', 'tres'].to_sentence(locale: :es)

# => "uno y dos"
['uno', 'dos'].to_sentence(locale: :es)

# last_word_connector: " o al menos "
# two_words_connector: " y "
# words_connector: " o "
# array:
# support:
# es:
#
# Given this locale dictionary:

Using :locale option:

# => "one or two or at least three"
['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')

# => "one-two"
['one', 'two'].to_sentence(two_words_connector: '-')

# => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale
['one', 'two'].to_sentence(passing: 'invalid option')

['one', 'two', 'three'].to_sentence # => "one, two, and three"
['one', 'two'].to_sentence # => "one and two"
['one'].to_sentence # => "one"
[].to_sentence # => ""

==== Examples

corresponding dictionary file.
the connector options defined on the 'support.array' namespace in the
* :locale - If +i18n+ is available, you can set a locale and use
in arrays with two elements (default: " and ").
* :two_words_connector - The sign or word used to join the elements
in arrays with three or more elements (default: ", and ").
* :last_word_connector - The sign or word used to join the last element
element in arrays with three or more elements (default: ", ").
* :words_connector - The sign or word used to join all but the last

==== Options

ArgumentError.
pass an option key that doesn't exist in the list below, it will raise an
You can pass the following options to change the default behavior. If you

joined by the connector word.
Converts the array to a comma-separated sentence where the last element is
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

def to_xml(options = {})




1
2008-03-07T09:58:18+01:00
1
1
2008-03-07T09:58:18+01:00




Message.all.to_xml(skip_types: true)

The +options+ hash is passed downwards:

You can change it with the :children option.
By default name of the node for the children of root is root.singularize.




customer_with_no_projects.projects.to_xml(root: 'projects')

To ensure a meaningful root element use the :root option:




[].to_xml

If the collection is empty the root element is "nil-classes" by default:



3


1
2




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

Otherwise the root element is "objects":



...
2008-04-15
1567
57230.0


...
2008-04-09
1567
20000.0




customer.projects.to_xml

if all elements belong to the same type and that's not Hash:
The root node reflects the class name of the first element in plural

not then an exception is raised.
All elements are expected to respond to +to_xml+, if any of them does

in XML to this method.
on each element. Active Record collections delegate their representation
Returns a string that represents the array in XML by invoking +to_xml+
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