Class: Array
- Defined in:
- motion/core_ext/object/to_json.rb,
motion/_stdlib/array.rb,
motion/core_ext/array.rb,
motion/core_ext/array/wrap.rb,
motion/core_ext/array/access.rb,
motion/core_ext/object/blank.rb,
motion/core_ext/array/grouping.rb,
motion/core_ext/object/deep_dup.rb,
motion/core_ext/object/to_param.rb,
motion/core_ext/object/to_query.rb,
motion/core_ext/array/conversions.rb,
motion/core_ext/array/extract_options.rb,
motion/core_ext/array/prepend_and_append.rb
Overview
For more complex objects (Array/Hash): Convert an object into a “JSON-ready” representation composed of primitives like Hash, Array, String, Numeric, and true/false/nil. Recursively calls #as_json to the object to recursively build a fully JSON-ready object.
This allows developers to implement #as_json without having to worry about what base types of objects they are allowed to return or having to remember to call #as_json recursively.
Direct Known Subclasses
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 ⇒ Object
-
#deep_dup ⇒ Object
Returns a deep copy of array.
-
#extract_options! ⇒ Object
Extracts options from a set of arguments.
-
#from(position) ⇒ Object
Returns the tail of the array from
position
. -
#has_hash_key?(key) ⇒ Boolean
If any item in the array has the key == ‘key` true, otherwise false.
-
#has_hash_value?(key) ⇒ Boolean
If any item in the array has the value == ‘key` true, otherwise false Of good use when writing specs.
-
#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
. - #reverse_each ⇒ Object
-
#second ⇒ Object
Equal to
self[1]
. -
#split(value = nil, &block) ⇒ Object
Divides the array into one or more subarrays based on a delimiting
value
or the result of an optional block. -
#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_json ⇒ Object
Calls
as_json
on all its elements and converts to a string. -
#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.
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 tryto_a
if the returned value isnil
, butArray.wrap
returns such anil
right away. -
If the returned value from
to_ary
is neithernil
nor anArray
object,Kernel#Array
raises an exception, whileArray.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}]
There’s also a related idiom that uses the splat operator:
[*object]
which for nil
returns []
, and calls to Array(object)
otherwise.
Thus, in this case the behavior may be different for nil
, and the differences with Kernel#Array
explained above apply to the rest of object
s.
36 37 38 39 40 41 42 43 44 |
# File 'motion/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 |
Instance Method Details
#as_json ⇒ Object
125 126 127 |
# File 'motion/core_ext/object/to_json.rb', line 125 def as_json map { |v| (v.respond_to?(:as_json) ? v.as_json : v) } end |
#deep_dup ⇒ Object
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
25 26 27 |
# File 'motion/core_ext/object/deep_dup.rb', line 25 def deep_dup map { |it| it.deep_dup } 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.
4 5 6 7 8 9 10 |
# File 'motion/core_ext/array/extract_options.rb', line 4 def if last.is_a?(Hash) pop else {} end end |
#from(position) ⇒ Object
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) # => []
8 9 10 |
# File 'motion/core_ext/array/access.rb', line 8 def from(position) self[position, length] || [] end |
#has_hash_key?(key) ⇒ Boolean
If any item in the array has the key == ‘key` true, otherwise false. Of good use when writing specs.
4 5 6 7 8 9 |
# File 'motion/core_ext/array.rb', line 4 def has_hash_key?(key) self.each do |entity| return true if entity.has_key? key end return false end |
#has_hash_value?(key) ⇒ Boolean
If any item in the array has the value == ‘key` true, otherwise false Of good use when writing specs.
13 14 15 16 17 18 |
# File 'motion/core_ext/array.rb', line 13 def has_hash_value?(key) self.each do |entity| entity.each_pair{|hash_key, value| return true if value == key} end return false 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 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"]
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'motion/core_ext/array/grouping.rb', line 57 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.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 |
#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 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"]
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'motion/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([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 |
#reverse_each ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 |
# File 'motion/_stdlib/array.rb', line 2 def reverse_each return to_enum(:reverse_each) unless block_given? i = size - 1 while i >= 0 yield self[i] i -= 1 end self end |
#second ⇒ Object
Equal to self[1]
.
%w( a b c d e ).second # => "b"
25 26 27 |
# File 'motion/core_ext/array/access.rb', line 25 def second self[1] end |
#split(value = nil, &block) ⇒ 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]]
88 89 90 91 92 93 94 95 96 97 98 |
# File 'motion/core_ext/array/grouping.rb', line 88 def split(value = nil, &block) inject([[]]) do |results, element| if block && block.call(element) || value == element results << [] else results.last << element end results end end |
#to(position) ⇒ Object
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) # => []
18 19 20 |
# File 'motion/core_ext/array/access.rb', line 18 def to(position) first position + 1 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. Having this model:
class Blog < ActiveRecord::Base
def to_s
title
end
end
Blog.all.map(&:title) #=> ["First Post", "Second Post", "Third post"]
to_formatted_s
shows us:
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"
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'motion/core_ext/array/conversions.rb', line 72 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_json ⇒ Object
Calls as_json
on all its elements and converts to a string.
130 131 132 |
# File 'motion/core_ext/object/to_json.rb', line 130 def to_json NSJSONSerialization.dataWithJSONObject(as_json, options: 0, error: nil).to_s 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.
32 33 34 |
# File 'motion/core_ext/object/to_param.rb', line 32 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"
16 17 18 19 |
# File 'motion/core_ext/object/to_query.rb', line 16 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.
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
.
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 ”).[].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”
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'motion/core_ext/array/conversions.rb', line 31 def to_sentence( = {}) .assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector) default_connectors = { :words_connector => ', ', :two_words_connector => ' and ', :last_word_connector => ', and ' } = default_connectors.merge!() 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 |