Class: Array
- Defined in:
- lib/quality_extensions/array/sum.rb,
lib/quality_extensions/array/mean.rb,
lib/quality_extensions/range_list.rb,
lib/quality_extensions/array/average.rb,
lib/quality_extensions/array/justify.rb,
lib/quality_extensions/array/classify.rb,
lib/quality_extensions/array/group_by.rb,
lib/quality_extensions/array/sequence.rb,
lib/quality_extensions/helpers/numbers.rb,
lib/quality_extensions/array/shell_escape.rb,
lib/quality_extensions/array/delete_if_bang.rb,
lib/quality_extensions/array/to_a_recursive.rb,
lib/quality_extensions/array/to_query_string.rb
Overview
–
- Author
-
Tyler Rick
- Copyright
-
Copyright © 2007 QualitySmith, Inc.
- License
-
Ruby License
- Submit to Facets?
-
Yes.
++
Instance Method Summary collapse
-
#after(value) ⇒ Object
Returns the value after the given value.
-
#average ⇒ Object
Calculates the arithmetic average (mean) of the elements in the array as a
Float
. -
#before(value) ⇒ Object
Returns the value previous to the given value.
-
#classify(&block) ⇒ Object
Classifies the array by the return value of the given block and returns a hash of => array of elements pairs.
-
#delete_if!(&block) ⇒ Object
Like partition, in that it creates two arrays, the first containing the elements of enum for which the block evaluates to false, the second containing the rest, only instead of returning both arrays, it changes
self
for the first array (those for which the block evaluates to false) and thus only needs to return the second array (those for which the block evaluates to true) (1..6).partition {|i| i % 3 == 0} # => [[3, 6], [1, 2, 4, 5]]. -
#expand_ranges ⇒ Object
Converts array to a RangeList and expands all Ranges contained in this array, replacing the range with the list of elements that the range represents (range.
to_a
) . - #extract_options! ⇒ Object
-
#group_by(column_index, *args) ⇒ Object
Breaks an array into a hash of smaller arrays, making a new group for each unique value in the specified column.
-
#ljust_columns(padstr = ' ') ⇒ Object
In each column of a table (2-dimensional array) of strings, pads the string with
padstr
(using ljust) so that all strings in that column have the same length. -
#ljust_columns!(padstr = ' ') ⇒ Object
In-place version of ljust_columns.
-
#ljust_rows(padstr = ' ') ⇒ Object
In each row of a table (2-dimensional array) of strings, pads the string with
padstr
(using ljust) so that all strings in that row have the same length. -
#ljust_rows!(padstr = ' ') ⇒ Object
In-place version of ljust_rows.
-
#mean ⇒ Object
Calculates the arithmetic average (mean) of the elements in the array as a
Float
. -
#rjust_columns(padstr = ' ') ⇒ Object
In each column of a table (2-dimensional array) of strings, pads the string with
padstr
(using rjust) so that all strings in that column have the same length. -
#rjust_columns!(padstr = ' ') ⇒ Object
In-place version of rjust_columns.
-
#rjust_rows(padstr = ' ') ⇒ Object
In each row of a table (2-dimensional array) of strings, pads the string with
padstr
(using rjust) so that all strings in that row have the same length. -
#rjust_rows!(padstr = ' ') ⇒ Object
In-place version of rjust_rows.
-
#select_if!(&block) ⇒ Object
Like partition, in that it creates two arrays, the first containing the elements of enum for which the block evaluates to false, the second containing the rest, only instead of returning both arrays, it changes
self
for the first array (those for which the block evaluates to false) and thus only needs to return the second array (those for which the block evaluates to true). -
#select_if_with_index!(&block) ⇒ Object
Note that self is not modified (the values are not deleted) until it has finished iterating through elements and has given a chance for you to decide the fate of each element.
- #shell_escape ⇒ Object
- #sum ⇒ Object
-
#to_a_recursive ⇒ Object
A lot like array.flatten, except that it will also “flatten” ranges (by converting range to range.to_a) and any other objects that respond to to_a contained in the array in addition to arrays contained in the array.
-
#to_query_string(key) ⇒ Object
Converts into a string that can be used as the query string of a URL (for example,
?key[]=val1&key[]=val2
). - #to_range_list ⇒ Object
Instance Method Details
#after(value) ⇒ Object
Returns the value after the given value. The value before the last is the first. Returns nil if the given value is not in the array.
Example:
sequence = ['a', 'b', 'c']
sequence.after('a') => 'b'
sequence.after('b') => 'c'
sequence.after('c') => 'a'
sequence.after('d') => nil
34 35 36 37 |
# File 'lib/quality_extensions/array/sequence.rb', line 34 def after(value) return nil unless include? value self[(index(value).to_i + 1) % length] end |
#average ⇒ Object
Calculates the arithmetic average (mean) of the elements in the array as a Float
.
irb -> [1, 3, 3].average
=> 2.33333333333333
14 15 16 17 18 19 20 21 |
# File 'lib/quality_extensions/array/average.rb', line 14 def average if self.size == 0 raise ZeroDivisionError end self.inject(0.0) do |sum, item| sum + item.to_f end / self.size end |
#before(value) ⇒ Object
Returns the value previous to the given value. The value previous to the first is the last. Returns nil if the given value is not in the array.
Example:
sequence = ['a', 'b', 'c']
sequence.before('a') => 'c'
sequence.before('b') => 'a'
sequence.before('c') => 'b'
sequence.before('d') => nil
19 20 21 22 |
# File 'lib/quality_extensions/array/sequence.rb', line 19 def before(value) return nil unless include? value self[(index(value).to_i - 1) % length] end |
#classify(&block) ⇒ Object
Classifies the array by the return value of the given block and returns a hash of => array of elements pairs.
The block is called once for each element of the array, passing the element as parameter.
Breaks an array into a hash of smaller arrays, making a new group for each unique value returned by the block. Each unique value becomes a key in the hash.
Example:
[
['a', 1],
['a', 2],
['b', 3],
['b', 4],
].classify {|o| o[0]}
=>
{
"a" => [['a', 1], ['a', 2]],
"b" => [['b', 3], ['b', 4]]
}
38 39 40 41 42 43 44 45 |
# File 'lib/quality_extensions/array/classify.rb', line 38 def classify(&block) hash = {} each do |element| classification = yield(element) (hash[classification] ||= []) << element end hash end |
#delete_if!(&block) ⇒ Object
Like partition, in that it creates two arrays, the first containing the elements of enum for which the block evaluates to false, the second containing the rest, only instead of returning both arrays, it changes self
for the first array (those for which the block evaluates to false) and thus only needs to return the second array (those for which the block evaluates to true)
(1..6).partition {|i| i % 3 == 0} # => [[3, 6], [1, 2, 4, 5]]
a = (1..6).to_a
a.delete_if! {|i| i % 3 == 0} # => [3, 6]
a # => [1, 2, 4, 5]
similar to delete_if / reject!, but modifies self in place (removes elements from self) and rather than simply discarding the deleted elements, it returns an array containing those elements removed (similar to partition)
a more generic version of Facets’ delete_values; that can only be used to delete if a value matches exactly; this can use any arbitrary comparison to determine whether or not to delete element
name?:
modify!
delete_if_returning_deleted
shift_unless :)
82 83 84 85 86 87 88 |
# File 'lib/quality_extensions/array/delete_if_bang.rb', line 82 def delete_if!(&block) d = [] #each{ |v| d << delete(v) if yield v; puts "yield #{v} returned #{yield v}"} # didn't work because the deleting messed up the each and not all elements were visited each{ |v| d << v if yield v} delete_values(*d) d end |
#expand_ranges ⇒ Object
Converts array to a RangeList and expands all Ranges contained in this array, replacing the range with the list of elements that the range represents (range.to_a
) .
127 128 129 |
# File 'lib/quality_extensions/range_list.rb', line 127 def to_range_list. end |
#extract_options! ⇒ Object
14 15 16 |
# File 'lib/quality_extensions/helpers/numbers.rb', line 14 def last.is_a?(::Hash) ? pop : {} end |
#group_by(column_index, *args) ⇒ Object
Breaks an array into a hash of smaller arrays, making a new group for each unique value in the specified column.
Each unique value becomes a key in the hash.
Example:
[
['a', 1],
['a', 2],
['b', 3],
['b', 4],
].group_by(0)
=>
"a"=>[[1], [2]],
"b"=>[[3], [4]]
Options:
* <tt>delete_key</tt>: deletes the key from the corresponding array if true (default true)
Example:
[
['a', 1],
['a', 2],
['b', 3],
['b', 4],
].group_by(0, :delete_key => false)
=>
"a"=>[['a', 1], ['a', 2]],
"b"=>[['b', 3], ['b', 4]]
*Notes*:
* <tt>self</tt> must be in the shape of a "table" (that is, a rectangular-shaped, two-dimensional array = an array of arrays,
each member array being of the same size (the "width" of the table)).
* This is different from the GROUP BY in SQL in that it doesn't apply an aggregate (like sum or average) to each group -- it just returns each group unmodified.
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/quality_extensions/array/group_by.rb', line 54 def group_by(column_index, *args) = (if args.last.is_a?(Hash) then args.pop else {} end) hash = {} self.each do |row| row_to_keep = row.dup row_to_keep.delete_values_at(column_index) unless [:delete_key] == false hash[row[column_index]] ||= [] hash[row[column_index]] << row_to_keep end hash end |
#ljust_columns(padstr = ' ') ⇒ Object
In each column of a table (2-dimensional array) of strings, pads the string with padstr
(using ljust) so that all strings in that column have the same length.
[['a', 'bb'],
['aaa', 'b' ]].ljust_columns
> [[‘a ’, ‘bb’],
['aaa', 'b ']]
The new values in the table will be strings even if they were not originally (1 might turn into ‘1 ’, for example).
26 27 28 29 30 |
# File 'lib/quality_extensions/array/justify.rb', line 26 def ljust_columns(padstr = ' ') new = self.deep_copy new.ljust_columns!(padstr) new end |
#ljust_columns!(padstr = ' ') ⇒ Object
In-place version of ljust_columns.
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/quality_extensions/array/justify.rb', line 47 def ljust_columns!(padstr = ' ') matrix = Matrix[*self] matrix.column_vectors.each do |column| max_length_in_col = column.max_by { |el| el.to_s.length }.to_s.length column.each_with_index { |el, i| column[i] = el.to_s.ljust(max_length_in_col, padstr) } end self end |
#ljust_rows(padstr = ' ') ⇒ Object
In each row of a table (2-dimensional array) of strings, pads the string with padstr
(using ljust) so that all strings in that row have the same length.
[['a' , 'aa' , 'a' ],
['bbb', 'b' , 'b' ]].ljust_rows
> [[‘a ’ , ‘aa’ , ‘a ’ ],
['bbb', 'b ', 'b ']]
The new values in the table will be strings even if they were not originally (1 might turn into ‘1 ’, for example).
69 70 71 72 73 |
# File 'lib/quality_extensions/array/justify.rb', line 69 def ljust_rows(padstr = ' ') new = self.deep_copy new.ljust_rows!(padstr) new end |
#ljust_rows!(padstr = ' ') ⇒ Object
In-place version of ljust_rows.
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/quality_extensions/array/justify.rb', line 91 def ljust_rows!(padstr = ' ') matrix = Matrix[*self] matrix.row_vectors.each do |row| max_length_in_row = row.max_by { |el| el.to_s.length }.to_s.length row.each_with_index { |el, i| row[i] = el.to_s.ljust(max_length_in_row, padstr) } end self end |
#mean ⇒ Object
Calculates the arithmetic average (mean) of the elements in the array as a Float
.
irb -> [1, 3, 3].average
=> 2.33333333333333
14 15 16 17 18 19 20 21 |
# File 'lib/quality_extensions/array/mean.rb', line 14 def mean if self.size == 0 raise ZeroDivisionError end self.inject(0.0) do |sum, item| sum + item.to_f end / self.size end |
#rjust_columns(padstr = ' ') ⇒ Object
In each column of a table (2-dimensional array) of strings, pads the string with padstr
(using rjust) so that all strings in that column have the same length.
[[ 'a', 'bb'],
['aaa', 'b']].rjust_columns
> [[‘ a’, ‘bb’],
['aaa', ' b']]
The new values in the table will be strings even if they were not originally (1 might turn into ‘1 ’, for example).
116 117 118 119 120 |
# File 'lib/quality_extensions/array/justify.rb', line 116 def rjust_columns(padstr = ' ') new = self.deep_copy new.rjust_columns!(padstr) new end |
#rjust_columns!(padstr = ' ') ⇒ Object
In-place version of rjust_columns.
124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/quality_extensions/array/justify.rb', line 124 def rjust_columns!(padstr = ' ') matrix = Matrix[*self] matrix.column_vectors.each do |column| max_length_in_col = column.max_by { |el| el.to_s.length }.to_s.length column.each_with_index { |el, i| column[i] = el.to_s.rjust(max_length_in_col, padstr) } end self end |
#rjust_rows(padstr = ' ') ⇒ Object
In each row of a table (2-dimensional array) of strings, pads the string with padstr
(using rjust) so that all strings in that row have the same length.
[[ 'a', 'aa', 'a'],
['bbb', 'b', 'b']].rjust_rows
> [[ ‘ a’, ‘aa’, ‘ a’],
['bbb', ' b', ' b']]
The new values in the table will be strings even if they were not originally (1 might turn into ‘1 ’, for example).
146 147 148 149 150 |
# File 'lib/quality_extensions/array/justify.rb', line 146 def rjust_rows(padstr = ' ') new = self.deep_copy new.rjust_rows!(padstr) new end |
#rjust_rows!(padstr = ' ') ⇒ Object
In-place version of rjust_rows.
154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/quality_extensions/array/justify.rb', line 154 def rjust_rows!(padstr = ' ') matrix = Matrix[*self] matrix.row_vectors.each do |row| max_length_in_row = row.max_by { |el| el.to_s.length }.to_s.length row.each_with_index { |el, i| row[i] = el.to_s.rjust(max_length_in_row, padstr) } end self end |
#select_if!(&block) ⇒ Object
Like partition, in that it creates two arrays, the first containing the elements of enum for which the block evaluates to false, the second containing the rest, only instead of returning both arrays, it changes self
for the first array (those for which the block evaluates to false) and thus only needs to return the second array (those for which the block evaluates to true)
this is analagous to what shift (or pop) does: it shifts (or pops) an element off of a collection and simultaneously returns that element which was shifted (or popped) off
Example:
orig_a = a = (1..6).to_a
b = a.select_if! {|i| i % 3 == 0} # => [1, 2, 4, 5]
a # => [3, 6]
This is identical to doing this:
orig_a = a = (1..6).to_a
a, b = a.partition {|i| i % 3 == 0}
a # => [3, 6]
b # => [1, 2, 4, 5]
except that in the case of partition, orig_a and a are now to different objects, whereas with select_if, a remains the same object and is modified in place.
name?:
modify!
select_if_returning_deleted
shift_if :)
39 40 41 42 43 44 |
# File 'lib/quality_extensions/array/delete_if_bang.rb', line 39 def select_if!(&block) d = [] each{ |v| d << v unless yield v} delete_values(*d) d end |
#select_if_with_index!(&block) ⇒ Object
Note that self is not modified (the values are not deleted) until it has finished iterating through elements and has given a chance for you to decide the fate of each element. (So if, for instance, you want to refer to the previous value, you can do that with select_if_with_index! by using array, even if array is “scheduled for deletion”, because it will not have been deleted yet.)
Example: args_for_vim = ARGV.delete_if! {|arg, i|
arg =~ /^-c/ || ARGV[i-1] =~ /^-c/ \
|| arg =~ /^\+/
}
56 57 58 59 60 61 |
# File 'lib/quality_extensions/array/delete_if_bang.rb', line 56 def select_if_with_index!(&block) d = [] each_with_index{ |v,i| d << v unless yield v,i} delete_values(*d) d end |
#shell_escape ⇒ Object
16 17 18 |
# File 'lib/quality_extensions/array/shell_escape.rb', line 16 def shell_escape self.map(&:shell_escape).map(&:to_s) end |
#sum ⇒ Object
11 12 13 |
# File 'lib/quality_extensions/array/sum.rb', line 11 def sum inject( nil ) { |sum,x| sum ? sum+x : x } end |
#to_a_recursive ⇒ Object
A lot like array.flatten, except that it will also “flatten” ranges (by converting range to range.to_a) and any other objects that respond to to_a contained in the array in addition to arrays contained in the array. Compare with Array#expand_ranges
12 13 14 15 16 17 18 19 20 21 |
# File 'lib/quality_extensions/array/to_a_recursive.rb', line 12 def to_a_recursive map do |item| # Assume that all arrays contain only elements that do not respond to to_a_recursive or arrays. if item.respond_to? :to_a_recursive item.to_a_recursive else item.to_a end end end |
#to_query_string(key) ⇒ Object
Converts into a string that can be used as the query string of a URL (for example, ?key[]=val1&key[]=val2
).
Example:
[
'Fred',
'Sam'
].to_query_string('names')
==> "names[]=Fred&names[]=Sam"
<tt>key</tt> is the name of the key in params that will receive the array when you load the page. So, for example, if you go to page with this query string (key = "names"): <tt>?names[]=Fred&names[]=Sam</tt>, params will be have a key "names", like so: <tt>{"names"=>["Fred", "Sam"]}</tt>.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/quality_extensions/array/to_query_string.rb', line 23 def to_query_string(key) elements = [] self.each do |value| _key = key + '[]' if value.is_a? Array raise "Array#to_query_string only works on flat (1-dimensional) arrays." elsif value.respond_to? :to_query_string value = value.to_query_string(_key) else value = CGI.escape value.to_s end elements << _key + '=' + value end elements.join('&') end |