Class: Array
- Defined in:
- activesupport/lib/active_support/json/encoding.rb,
activesupport/lib/active_support/core_ext/array/wrap.rb,
activesupport/lib/active_support/core_ext/object/blank.rb,
activesupport/lib/active_support/core_ext/array/access.rb,
activesupport/lib/active_support/core_ext/array/uniq_by.rb,
activesupport/lib/active_support/core_ext/array/grouping.rb,
activesupport/lib/active_support/core_ext/object/to_param.rb,
activesupport/lib/active_support/core_ext/object/to_query.rb,
activesupport/lib/active_support/core_ext/array/conversions.rb,
activesupport/lib/active_support/core_ext/array/random_access.rb,
activesupport/lib/active_support/core_ext/array/extract_options.rb
Direct Known Subclasses
ActionController::TestRequest::Result, ActionView::PathSet, ActiveModel::ObserverArray, ActiveSupport::Callbacks::CallbackChain, Mime::Mimes, Rails::Initializable::Collection, Rails::Paths::Path
Class Method Summary collapse
-
.wrap(object) ⇒ Object
Wraps its argument in an array unless it is already an array (or array-like).
Instance Method Summary collapse
-
#as_json(options = nil) ⇒ Object
:nodoc:.
-
#encode_json(encoder) ⇒ Object
:nodoc:.
-
#extract_options! ⇒ Object
Extracts options from a set of arguments.
-
#fifth ⇒ Object
Equal to
self[4]
. -
#forty_two ⇒ Object
Equal to
self[41]
. -
#fourth ⇒ Object
Equal to
self[3]
. -
#from(position) ⇒ Object
Returns the tail of the array from
position
. -
#in_groups(number, fill_with = nil) ⇒ Object
Splits or iterates over the array in
number
of groups, padding any remaining slots withfill_with
unless it isfalse
. -
#in_groups_of(number, fill_with = nil) ⇒ Object
Splits or iterates over the array in groups of size
number
, padding any remaining slots withfill_with
unless it isfalse
. -
#sample(n = nil) ⇒ Object
Backport of Array#sample based on Marc-Andre Lafortune’s github.com/marcandre/backports/ Returns a random element or
n
random elements from the array. -
#second ⇒ Object
Equal to
self[1]
. -
#split(value = nil) ⇒ Object
Divides the array into one or more subarrays based on a delimiting
value
or the result of an optional block. -
#third ⇒ Object
Equal to
self[2]
. -
#to(position) ⇒ Object
Returns the beginning of the array up to
position
. -
#to_formatted_s(format = :default) ⇒ Object
(also: #to_s)
Converts a collection of elements into a formatted string by calling
to_s
on all elements and joining them:. -
#to_param ⇒ Object
Calls
to_param
on all its elements and joins the result with slashes. -
#to_query(key) ⇒ Object
Converts an array into a string suitable for use as a URL query string, using the given
key
as the param name. -
#to_sentence(options = {}) ⇒ Object
Converts the array to a comma-separated sentence where the last element is joined by the connector word.
-
#to_xml(options = {}) ⇒ Object
Returns a string that represents the array in XML by invoking
to_xml
on each element. -
#uniq_by ⇒ Object
Returns an unique array based on the criteria given as a
Proc
. -
#uniq_by! ⇒ Object
Same as uniq_by, but modifies self.
Class Method Details
.wrap(object) ⇒ Object
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.
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 such a nil
right away.
-
If the returned value from
to_ary
is neithernil
nor anArray
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-casesnil
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 objects.
39 40 41 42 43 44 45 46 47 |
# 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 else [object] end end |
Instance Method Details
#as_json(options = nil) ⇒ Object
:nodoc:
215 216 217 218 219 |
# File 'activesupport/lib/active_support/json/encoding.rb', line 215 def as_json( = nil) #:nodoc: # use encoder as a proxy to call as_json on all elements, to protect from circular references encoder = && [:encoder] || ActiveSupport::JSON::Encoding::Encoder.new() map { |v| encoder.as_json(v) } end |
#encode_json(encoder) ⇒ Object
:nodoc:
221 222 223 224 |
# File 'activesupport/lib/active_support/json/encoding.rb', line 221 def encode_json(encoder) #:nodoc: # we assume here that the encoder has already run as_json on self and the elements, so we run encode_json directly "[#{map { |v| v.encode_json(encoder) } * ','}]" end |
#extract_options! ⇒ Object
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 (*args)
args.
end
(1, 2) # => {}
(1, 2, :a => :b) # => {:a=>:b}
22 23 24 25 26 27 28 |
# File 'activesupport/lib/active_support/core_ext/array/extract_options.rb', line 22 def if last.is_a?(Hash) && last. pop else {} end end |
#fifth ⇒ Object
Equal to self[4]
.
38 39 40 |
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 38 def fifth self[4] end |
#forty_two ⇒ Object
Equal to self[41]
. Also known as accessing “the reddit”.
43 44 45 |
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 43 def forty_two self[41] end |
#fourth ⇒ Object
Equal to self[3]
.
33 34 35 |
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 33 def fourth self[3] end |
#from(position) ⇒ Object
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()
8 9 10 |
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 8 def from(position) self[position, length] || [] end |
#in_groups(number, fill_with = nil) ⇒ Object
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, ' ') {|group| p group}
["1", "2", "3"]
["4", "5", " "]
["6", "7", " "]
%w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
["1", "2", "3"]
["4", "5"]
["6", "7"]
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'activesupport/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) ⇒ Object
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, ' ') {|group| p group}
["1", "2"]
["3", " "]
%w(1 2 3).in_groups_of(2, false) {|group| p group}
["1", "2"]
["3"]
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'activesupport/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) ⇒ Object
Backport of Array#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) # => []
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'activesupport/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.})" 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 ⇒ Object
Equal to self[1]
.
23 24 25 |
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 23 def second self[1] end |
#split(value = nil) ⇒ Object
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]]
87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'activesupport/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 ⇒ Object
Equal to self[2]
.
28 29 30 |
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 28 def third self[2] end |
#to(position) ⇒ Object
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()
18 19 20 |
# File 'activesupport/lib/active_support/core_ext/array/access.rb', line 18 def to(position) self[0..position] end |
#to_formatted_s(format = :default) ⇒ Object Also known as: to_s
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 prettier output:
Blog.all.to_formatted_s(:db) # => "First Post,Second Post,Third Post"
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'activesupport/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 |
#to_param ⇒ Object
Calls to_param
on all its elements and joins the result with slashes. This is used by url_for
in Action Pack.
29 30 31 |
# File 'activesupport/lib/active_support/core_ext/object/to_param.rb', line 29 def to_param collect { |e| e.to_param }.join '/' end |
#to_query(key) ⇒ Object
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"
19 20 21 22 |
# File 'activesupport/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_sentence(options = {}) ⇒ Object
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 ”)
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'activesupport/lib/active_support/core_ext/array/conversions.rb', line 11 def to_sentence( = {}) if defined?(I18n) default_words_connector = I18n.translate(:'support.array.words_connector', :locale => [:locale]) default_two_words_connector = I18n.translate(:'support.array.two_words_connector', :locale => [:locale]) default_last_word_connector = I18n.translate(:'support.array.last_word_connector', :locale => [:locale]) else default_words_connector = ", " default_two_words_connector = " and " default_last_word_connector = ", and " end .assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale) .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]}#{[:two_words_connector]}#{self[1]}" else "#{self[0...-1].join([:words_connector])}#{[:last_word_connector]}#{self[-1]}" end end |
#to_xml(options = {}) ⇒ Object
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
<?xml version="1.0" encoding="UTF-8"?>
<records type="array">
<record>
<bar type="integer">2</bar>
<foo type="integer">1</foo>
</record>
<record>
<baz type="integer">3</baz>
</record>
</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")
<?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>
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'activesupport/lib/active_support/core_ext/array/conversions.rb', line 136 def to_xml( = {}) require 'active_support/builder' unless defined?(Builder) = .dup [:indent] ||= 2 [:builder] ||= Builder::XmlMarkup.new(:indent => [:indent]) [: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 = [:builder] builder.instruct! unless .delete(:skip_instruct) root = ActiveSupport::XmlMini.rename_key([:root].to_s, ) children = .delete(:children) || root.singularize attributes = [: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, ) } yield builder if block_given? end end |
#uniq_by ⇒ Object
Returns an unique array based on the criteria given as a Proc
.
[1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
6 7 8 9 10 |
# File 'activesupport/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! ⇒ Object
Same as uniq_by, but modifies self.
13 14 15 |
# File 'activesupport/lib/active_support/core_ext/array/uniq_by.rb', line 13 def uniq_by! replace(uniq_by{ |i| yield(i) }) end |