класс Array
Публичные методы класса
Оборачивает свой аргумент в массив, если он не является уже массивом (или массивоподобным).
Конкретно:
-
Если аргумент
nilвозвращается пустой список. -
В противном случае, если аргумент отвечает на
to_aryон вызывается, и возвращается его результат. -
В противном случае возвращается массив с аргументом в качестве единственного элемента.
Array.wrap(nil) # => [] Array.wrap([1, 2, 3]) # => [1, 2, 3] Array.wrap(0) # => [0]
Этот метод аналогичен по назначению Kernel#Array, но есть некоторые различия:
-
Если аргумент отвечает на
to_aryметод вызывается.Kernel#Arrayпереходит к попыткеto_aесли возвращённое значение являетсяnil, ноArray.wrapвозвращаетnilсразу. -
Если возвращённое значение от
to_aryне является ниnil, ни объектомArray,Kernel#Arrayгенерирует исключение, в то время какArray.wrapнет, он просто возвращает значение. -
Он не вызывает
to_aдля аргумента, но возвращает пустой массив, если аргументnil.
Второй пункт легко объясняется на примере перечислителей:
Array(foo: :bar) # => [[:foo, :bar]]
Array.wrap(foo: :bar) # => [{:foo=>:bar}]
Также есть связанное выражение, которое использует оператор splat:
[*object]
что возвращает [] для nil, но вызывает Array(object) в противном случае.
Различия с Kernel#Array описанные выше, относятся к остальным object.
# File activesupport/lib/active_support/core_ext/array/wrap.rb, line 36
def self.wrap(object)
if object.nil?
[]
elsif object.respond_to?(:to_ary)
object.to_ary || [object]
else
[object]
end
end Публичные методы экземпляра
Возвращает глубокую копию массива.
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 { |it| it.deep_dup }
end Извлекает параметры из набора аргументов. Удаляет и возвращает последний элемент в массиве, если это хэш, в противном случае возвращает пустой хэш.
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 Равно self[4].
%w( a b c d e ).fifth # => "e"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 46 def fifth self[4] end
Равно self[41]. Также известно как доступ к «reddit».
(1..42).to_a.forty_two # => 42
# File activesupport/lib/active_support/core_ext/array/access.rb, line 53 def forty_two self[41] end
Равно self[3].
%w( a b c d e ).fourth # => "d"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 39 def fourth self[3] end
Возвращает хвост массива с позиции 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) # => []
# File activesupport/lib/active_support/core_ext/array/access.rb, line 8 def from(position) self[position, length] || [] end
Разделяет или итерирует массив на группы по number элементов, заполняя оставшиеся места значением fill_with, если оно не 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 55
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 Разделяет или итерирует массив на группы по number элементов, заполняя оставшиеся места значением fill_with, если оно не 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 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 Равно self[1].
%w( a b c d e ).second # => "b"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 25 def second self[1] end
Делит массив на один или несколько подмассивов на основе разделителя value или результата блока.
[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 86
def split(value = nil)
if block_given?
inject([[]]) do |results, element|
if yield(element)
results << []
else
results.last << element
end
results
end
else
results, arr = [[]], self.dup
until arr.empty?
if (idx = arr.index(value))
results.last.concat(arr.shift(idx))
arr.shift
results << []
else
results.last.concat(arr.shift(arr.size))
end
end
results
end
end Равно self[2].
%w( a b c d e ).third # => "c"
# File activesupport/lib/active_support/core_ext/array/access.rb, line 32 def third self[2] end
Возвращает начало массива до 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) # => []
# File activesupport/lib/active_support/core_ext/array/access.rb, line 18 def to(position) first position + 1 end
Расширяет Array#to_s для преобразования набора элементов в список идентификаторов, разделенных запятыми, если аргумент :db задан в качестве формата.
Blog.all.to_formatted_s(:db) # => "1,2,3"
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 89
def to_formatted_s(format = :default)
case format
when :db
if empty?
'null'
else
collect { |element| element.id }.join(',')
end
else
to_default_s
end
end Вызывает to_param для всех своих элементов и объединяет результат слешами. Используется в url_for в Action Pack.
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 39
def to_param
collect { |e| e.to_param }.join '/'
end Преобразует массив в строку, подходящую для использования в качестве строки запроса URL, используя заданное key в качестве имени параметра.
['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 47
def to_query(key)
prefix = "#{key}[]"
if empty?
nil.to_query(prefix)
else
collect { |value| value.to_query(prefix) }.join '&'
end
end Преобразует массив в предложение, разделенное запятыми, где последний элемент соединен союзом.
Вы можете передать следующие параметры, чтобы изменить стандартное поведение. Если вы передадите ключ параметра, который не существует в списке ниже, будет выброшено исключение ArgumentError.
Параметры
-
:words_connector- Знак или слово, используемые для объединения элементов в массивах с двумя или более элементами (по умолчанию: “, ”). -
:two_words_connector- Знак или слово, используемые для объединения элементов в массивах с двумя элементами (по умолчанию: “ и ”). -
:last_word_connector- Знак или слово, используемые для объединения последнего элемента в массивах с тремя или более элементами (по умолчанию: “, и ”). -
:locale- Еслиi18nдоступен, вы можете установить локаль и использовать параметры союза, определенные в пространстве имен 'support.array' в соответствующем файле словаря.
Примеры
[].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 ['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"
Использование параметра :locale:
# 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].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 Возвращает строку, представляющую массив в формате XML, вызывая to_xml для каждого элемента. Коллекции Active Record делегируют своё представление в формате XML этому методу.
Ожидается, что все элементы будут отвечать на to_xml, в противном случае будет выброшено исключение.
Корневой узел отражает имя класса первого элемента во множественном числе, если все элементы относятся к одному типу и это не хэш:
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> В противном случае корневой элемент — “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> Если коллекция пустая, корневой элемент по умолчанию — “nil-classes”:
[].to_xml <?xml version="1.0" encoding="UTF-8"?> <nil-classes type="array"/>
Чтобы гарантировать осмысленный корневой элемент, используйте параметр :root:
customer_with_no_projects.projects.to_xml(root: 'projects') <?xml version="1.0" encoding="UTF-8"?> <projects type="array"/>
По умолчанию имя узла для потомков корня — root.singularize. Вы можете изменить его с помощью параметра :children.
Хэш options передаётся вниз:
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 179
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
© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.