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.
# File activesupport/lib/active_support/core_ext/array/wrap.rb, line 37
def self.wrap(object)
if object.nil?
[]
elsif object.respond_to?(:to_ary)
object.to_ary || [object]
else
[object]
end
end 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 27 def deep_dup map(&:deep_dup) end
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 activesupport/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 Equal to self[4].
%w( a b c d e ).fifth # => "e"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 66 def fifth self[4] end
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 73 def forty_two self[41] end
Equal to self[3].
%w( a b c d e ).fourth # => "d"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 59 def fourth self[3] end
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 10 def from(position) self[position, length] || [] end
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 60
def in_groups(number, fill_with = nil)
# 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 { |g| yield(g) }
else
groups
end
end 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 20
def in_groups_of(number, fill_with = nil)
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) { |slice| yield(slice) }
else
collection.each_slice(number).to_a
end
end Wraps the array in an 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 14 def inquiry ActiveSupport::ArrayInquirer.new(self) end
Equal to self[1].
%w( a b c d e ).second # => "b"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 45 def second self[1] end
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 87 def second_to_last self[-2] end
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 91
def split(value = nil)
arr = dup
result = []
if block_given?
while (idx = arr.index { |i| yield i })
result << arr.shift(idx)
arr.shift
end
else
while (idx = arr.index(value))
result << arr.shift(idx)
arr.shift
end
end
result << arr
end Equal to self[2].
%w( a b c d e ).third # => "c"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 52 def third self[2] end
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 80 def third_to_last self[-3] end
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 22
def to(position)
if position >= 0
take position + 1
else
self[0..position]
end
end Extends Array#to_s to convert a collection of elements into a comma separated id list if :db argument is given as the format.
Blog.all.to_formatted_s(:db) # => "1,2,3" Blog.none.to_formatted_s(:db) # => "null" [1,2].to_formatted_s # => "[1, 2]"
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 91
def to_formatted_s(format = :default)
case format
when :db
if empty?
"null"
else
collect(&:id).join(",")
end
else
to_default_s
end
end 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 40 def to_param collect(&:to_param).join "/" end
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 48
def to_query(key)
prefix = "#{key}[]"
if empty?
nil.to_query(prefix)
else
collect { |value| value.to_query(prefix) }.join "&"
end
end 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.
: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 ”).
: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.
[].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 59
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 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 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> # File activesupport/lib/active_support/core_ext/array/conversions.rb, line 181
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 != 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" }
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 Returns a copy of the Array without the specified elements.
people = ["David", "Rafael", "Aaron", "Todd"] people.without "Aaron", "Todd" # => ["David", "Rafael"]
Note: This is an optimization of `Enumerable#without` that uses `Array#-` instead of `Array#reject` for performance reasons.
# File activesupport/lib/active_support/core_ext/array/access.rb, line 38 def without(*elements) self - elements end
© 2004–2017 David Heinemeier Hansson
Licensed under the MIT License.