Class: Array
- Includes:
- Indexable, Random::ArrayExtensions
- Defined in:
- lib/core/facets/boolean.rb,
lib/core/facets/to_hash.rb,
lib/standard/facets/set.rb,
lib/core/facets/array/pad.rb,
lib/core/facets/array/from.rb,
lib/core/facets/array/mode.rb,
lib/core/facets/array/only.rb,
lib/core/facets/array/pull.rb,
lib/standard/facets/random.rb,
lib/core/facets/array/index.rb,
lib/core/facets/array/merge.rb,
lib/core/facets/array/split.rb,
lib/core/facets/array/store.rb,
lib/core/facets/array/before.rb,
lib/core/facets/array/divide.rb,
lib/core/facets/array/rotate.rb,
lib/core/facets/array/select.rb,
lib/core/facets/array/splice.rb,
lib/core/facets/kernel/blank.rb,
lib/core/facets/array/conjoin.rb,
lib/core/facets/array/entropy.rb,
lib/core/facets/array/nonuniq.rb,
lib/core/facets/array/product.rb,
lib/core/facets/array/recurse.rb,
lib/core/facets/array/uniq_by.rb,
lib/supplemental/facets/tuple.rb,
lib/core/facets/array/collapse.rb,
lib/core/facets/array/contains.rb,
lib/core/facets/array/traverse.rb,
lib/standard/facets/shellwords.rb,
lib/core/facets/array/indexable.rb,
lib/core/facets/array/not_empty.rb,
lib/core/facets/enumerable/count.rb,
lib/core/facets/array/combination.rb,
lib/core/facets/array/commonality.rb,
lib/core/facets/array/permutation.rb,
lib/core/facets/array/probability.rb,
lib/core/facets/array/recursively.rb,
lib/core/facets/array/delete_unless.rb,
lib/core/facets/array/delete_values.rb,
lib/core/facets/object/object_state.rb,
lib/core-uncommon/facets/array/median.rb,
lib/core-uncommon/facets/array/op_pow.rb,
lib/core/facets/array/extract_options.rb,
lib/core-uncommon/facets/array/percentile.rb
Instance Method Summary collapse
- #_facets_index ⇒ Object
-
#after(value) ⇒ Object
Returns the value after the given value.
-
#before(value) ⇒ Object
Returns the value previous to the given value.
-
#collapse ⇒ Object
Simplify an array by flattening it then compacting it.
-
#combination(k = 2) ⇒ Object
Yields the block to each unique combination of n elements.
-
#commonality(&block) ⇒ Object
(also: #collisions)
Returns all items that are equal in terms of the supplied block.
-
#conjoin(*args, &block) ⇒ Object
This is more advanced form of #join.
-
#delete_unless(&block) ⇒ Object
Inverse of #delete_if.
-
#delete_values(*values) ⇒ Object
Delete multiple values from array.
-
#delete_values_at(*selectors) ⇒ Object
Delete multiple values from array given indexes or index range.
-
#divide(pattern) ⇒ Object
Divide on matching pattern.
-
#entropy ⇒ Object
Shannon’s entropy for an array - returns the average bits per symbol required to encode the array.
-
#extract_options! ⇒ Object
Extracts options from a set of arguments.
-
#from(i) ⇒ Object
Returns last n elements.
-
#ideal_entropy ⇒ Object
Returns the maximum possible Shannon entropy of the array with given size assuming that it is an “order-0” source (each element is selected independently of the next).
-
#index(obj = nil, &block) ⇒ Object
Allows #index to accept a block.
-
#median ⇒ Object
Returns the median for the array; nil if array is empty.
-
#merge!(other) ⇒ Object
In place #merge.
-
#mode ⇒ Object
In Statistics mode is the value that occurs most frequently in a given set of data.
-
#nonuniq ⇒ Object
(also: #duplicates)
Returns a list of non-unique elements.
- #nonuniq! ⇒ Object
-
#not_empty? ⇒ Boolean
Not empty?.
- #object_state(data = nil) ⇒ Object
-
#only ⇒ Object
Returns the only element in the array.
-
#pad(len, val = nil) ⇒ Object
Pad an array with a given
value
up to a givenlength
. -
#pad!(len, val = nil) ⇒ Object
Like #pad but changes the array in place.
-
#peek(i = 0) ⇒ Object
Peek at the top of the stack (the end of the array).
-
#percentile(p) ⇒ Object
Returns the percentile value for percentile p; nil if array is empty.
-
#permutation(n = size) ⇒ Object
Permutation provids the possible orders of an enumerable.
-
#poke(x, i = 0) ⇒ Object
Put an object on the bottom of the stack (front of the array).
- #power_set ⇒ Object
-
#probability ⇒ Object
Generates a hash mapping each unique element in the array to the relative frequency, i.e.
-
#product(*enums) ⇒ Object
(also: #**)
Provides the cartesian product of two or more arrays.
-
#recurse(*types) {|a| ... } ⇒ Object
Apply a block to array, and recursively apply that block to each sub-array or
types
. -
#recurse!(&block) ⇒ Object
In place form of #recurse.
-
#recursively(*types, &block) ⇒ Object
Apply a method to array, and recursively apply that method to each sub-array or
types
. -
#rotate(n = 1) ⇒ Object
Rotates an array’s elements from back to front n times.
-
#rotate!(n = 1) ⇒ Object
Same as #rotate, but acts in place.
-
#select! ⇒ Object
As with #select but modifies the Array in place.
- #shelljoin ⇒ Object
-
#shellwords ⇒ Object
Convert an array into command line parameters.
-
#splice(*args) ⇒ Object
Splice acts a combination of #slice! and #store.
-
#split(pattern) ⇒ Object
Split on matching pattern.
-
#thru(from, to = nil) ⇒ Object
Fetch values from a start index thru an end index.
-
#to_b ⇒ Object
Boolean conversion for not empty?.
-
#to_h(mode = nil) ⇒ Object
Converts an array into a hash.
-
#to_h_assoc ⇒ Object
When a mixed or multi-element accociative array is used, the result is as follows:.
-
#to_h_auto ⇒ Object
Converts an array into a hash.
-
#to_h_flat ⇒ Object
This is equivalent to Hash, but it will pad the array with a
nil
object if there are not an even number of elements. -
#to_h_multi ⇒ Object
When a mixed or multi-element accociative array is used, the result is as follows:.
-
#to_h_splat ⇒ Object
This is equivalent to Hash, but it will pad the array with a
nil
object if there are not an even number of elements. -
#to_t ⇒ Object
Convert an array into a tuple.
-
#traverse(&block) ⇒ Object
Returns a new array created by traversing the array and its sub-arrays, executing the given block on the elements.
-
#traverse!(&block) ⇒ Object
Like #recursive_map, but will change the array in place.
-
#uniq_by! ⇒ Object
Like #uniq, but determines uniqueness based on a given block.
Methods included from Indexable
#body, #ends, #first, #first=, #foot, #head, #last, #last=, #mid, #middle, #pos, #range, #tail
Methods included from Random::ArrayExtensions
#at_rand, #at_rand!, #pick, #pick!, #rand_index, #rand_subset, #shuffle, #shuffle!
Instance Method Details
#_facets_index ⇒ Object
5 |
# File 'lib/core/facets/array/index.rb', line 5 alias_method :_facets_index, :index |
#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.
Examples
sequence = ['a', 'b', 'c']
sequence.after('a') #=> 'b'
sequence.after('b') #=> 'c'
sequence.after('c') #=> 'a'
sequence.after('d') #=> nil
CREDIT: Tyler Rick
33 34 35 36 |
# File 'lib/core/facets/array/before.rb', line 33 def after(value) return nil unless include? value self[(index(value).to_i + 1) % length] 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.
Examples
sequence = ['a', 'b', 'c']
sequence.before('a') #=> 'c'
sequence.before('b') #=> 'a'
sequence.before('c') #=> 'b'
sequence.before('d') #=> nil
CREDIT: Tyler Rick
16 17 18 19 |
# File 'lib/core/facets/array/before.rb', line 16 def before(value) return nil unless include? value self[(index(value).to_i - 1) % length] end |
#collapse ⇒ Object
Simplify an array by flattening it then compacting it.
[1,[2,nil,[3]],nil,4].collapse #=> [1,2,3,4]
7 8 9 |
# File 'lib/core/facets/array/collapse.rb', line 7 def collapse flatten.compact end |
#combination(k = 2) ⇒ Object
Yields the block to each unique combination of n elements.
a = %w|a b c d|
a.combination(3)
produces
[["a", "b", "c"],
["a", "b", "d"],
["a", "c", "d"],
["b", "c", "d"]]
CREDIT: Florian Gross
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/core/facets/array/combination.rb', line 21 def combination(k=2) if block_given? s = to_a n = s.size return unless (1..n) === k idx = (0...k).to_a loop do yield s.values_at(*idx) i = k - 1 i -= 1 while idx[i] == n - k + i break if i < 0 idx[i] += 1 (i + 1 ... k).each {|j| idx[j] = idx[i] + j - i} end else to_enum(:combination, k) end end |
#commonality(&block) ⇒ Object Also known as: collisions
Returns all items that are equal in terms of the supplied block. If no block is given objects are considered to be equal if they return the same value for Object#hash and if obj1 == obj2.
[1, 2, 2, 3, 4, 4].commonality #=> { 2 => [2, 2], 4 => [4, 4] }
["foo", "bar", "a"].commonality { |str| str.length }
#=> { 3 => ["foo", "bar"] }
This can be useful, for instance, in determining all persons that share their last name with another person …
persons.collisions { |person| person.last_name }
CREDIT: Florian Gross
19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/core/facets/array/commonality.rb', line 19 def commonality(&block) had_no_block = !block block ||= lambda { |item| item } result = Hash.new { |hash, key| hash[key] = Array.new } each do |item| key = block.call(item) result[key] << item end result.reject! do |key, values| values.size <= 1 end # -- return had_no_block ? result.values.flatten : result return result end |
#conjoin(*args, &block) ⇒ Object
This is more advanced form of #join. It allows for fine control of separators.
NOTE: The old version used to default its separator to “, ” and default the terminating separator to “ and ”. This is no longer the case. You must specifically provide these parameters.
If no paramters are given, it acts like #join but will a space separator.
[1,2,3].conjoin
#=> "1 2 3"
Use comma+space and ‘and’ on tail.
[1,2,3].conjoin(', ', ' and ')
#=> "1, 2 and 3"
Use comma+space and ‘or’ on tail using :last option.
[1,2,3].conjoin(', ', :last => ' or ')
#=> "1, 2 or 3"
Use semicolon+space and ampersand on tail using index.
[1,2,3].conjoin('; ', -1 => ' & ')
#=> "1; 2 & 3"
Can take a block to determine separator.
[1,2,3,4].conjoin{ |i, a, b| i % 2 == 0 ? '.' : '-' }
#=> "1.2-3.4"
This makes very esoteric transformation possible.
[1,1,2,2].conjoin{ |i, a, b| a == b ? '=' : ' != ' }
#=> "1=1 != 2=2"
[1,2,3,4].conjoin{ |i, x, y| "<#{i} #{x} #{y}>" }
#=> "1<0 1 2>2<1 2 3>3<2 3 4>4"
There are also spacing options. Providing the :space option pads the separators.
[1,2,3].conjoin(',', '&', :space=>2)
#=> "1 , 2 & 3"
And the :spacer option can set an alternate spacing string.
[1,2,3].conjoin('|', '>', :space=>2, :spacer=>'-')
#=> "1--|--2-->--3"
CREDIT: Trans
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 82 83 84 85 86 |
# File 'lib/core/facets/array/conjoin.rb', line 57 def conjoin(*args, &block) return first.to_s if size < 2 = (Hash===args.last) ? args.pop : {} spacing = .delete(:space) || 0 spacer = .delete(:spacer) || " " space = spacer * spacing.to_i sep = [] if block_given? (size - 1).times do |i| sep << space + yield(i, *slice(i,2)) + space end else separator = args.shift || " " [-1] = args.shift if args.first [0] = .delete(:first) if .key?(:first) [-1] = .delete(:last) if .key?(:last) separator = space + separator + space sep = [separator] * (size - 1) .each{|i, s| sep[i] = space + s + space} end zip(sep).join end |
#delete_unless(&block) ⇒ Object
Inverse of #delete_if.
[1,2,3].delete_unless{ |x| x < 2 }
#=> [1]
CREDIT: Daniel Schierbeck
10 11 12 |
# File 'lib/core/facets/array/delete_unless.rb', line 10 def delete_unless(&block) delete_if { |element| not block.call(element) } end |
#delete_values(*values) ⇒ Object
Delete multiple values from array.
a = [1,2,3,4]
a.delete_values(1,2) #=> [1,2]
a #=> [3,4]
CREDIT: Trans
11 12 13 14 15 |
# File 'lib/core/facets/array/delete_values.rb', line 11 def delete_values(*values) d = [] values.each{ |v| d << delete(v) } d end |
#delete_values_at(*selectors) ⇒ Object
Delete multiple values from array given indexes or index range.
a = [1,2,3,4]
a.delete_values_at(1,2) #=> [2,3]
a #=> [1,4]
a = [1,2,3,4]
a.delete_values_at(0..2) #=> [1,2,3]
a #=> [4]
NOTE: It would be nice to see #delete_at incorporate this funcitonaility.
CREDIT: Trans
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/core/facets/array/delete_values.rb', line 32 def delete_values_at(*selectors) idx = [] selectors.each{ |i| case i when Range idx.concat( i.to_a ) else idx << i.to_i end } idx.uniq! dvals = values_at(*idx) idx = (0...size).to_a - idx self.replace( values_at(*idx) ) return dvals end |
#divide(pattern) ⇒ Object
Divide on matching pattern.
['a1','b1','a2','b2'].divide(/^a/)
#=> [['a1','b1'],['a2','b2']]
CREDIT: Trans
10 11 12 13 14 15 16 17 |
# File 'lib/core/facets/array/divide.rb', line 10 def divide(pattern) memo = [] each do |obj| memo.push [] if pattern === obj memo.last << obj end memo end |
#entropy ⇒ Object
Shannon’s entropy for an array - returns the average bits per symbol required to encode the array. Lower values mean less “entropy” - i.e. less unique information in the array.
e = %w{ a b c d e e e }.entropy
("%.3f" % e) #=> "2.128"
CREDIT: Derek
16 17 18 19 20 21 22 23 24 |
# File 'lib/core/facets/array/entropy.rb', line 16 def entropy arr = self probHash = arr.probability # -- h is the Shannon entropy of the array h = -1.to_f * probHash.keys.inject(0.to_f) do |sum, i| sum + (probHash[i] * (Math.log(probHash[i])/Math.log(2.to_f))) end h 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}
23 24 25 26 27 28 29 |
# File 'lib/core/facets/array/extract_options.rb', line 23 def if Hash === last && last. pop else {} end end |
#from(i) ⇒ Object
Returns last n elements.
%w{W o r l d}.from(3) #=> %w{l d}
7 8 9 10 |
# File 'lib/core/facets/array/from.rb', line 7 def from(i) return self if i >= size self[i, size - i] end |
#ideal_entropy ⇒ Object
Returns the maximum possible Shannon entropy of the array with given size assuming that it is an “order-0” source (each element is selected independently of the next).
CREDIT: Derek
32 33 34 35 36 |
# File 'lib/core/facets/array/entropy.rb', line 32 def ideal_entropy arr = self unitProb = 1.0.to_f / arr.size.to_f (-1.to_f * arr.size.to_f * unitProb * Math.log(unitProb)/Math.log(2.to_f)) end |
#index(obj = nil, &block) ⇒ Object
Allows #index to accept a block.
['a', 'b', 'c'].index{ |x| x.upcase == 'C' } #=> 2
IMPORTANT: This is one of the few core overrides in Facets.
12 13 14 15 16 17 18 |
# File 'lib/core/facets/array/index.rb', line 12 def index(obj=nil, &block) if block_given? _facets_index(find(&block)) else _facets_index(obj) end end |
#median ⇒ Object
Returns the median for the array; nil if array is empty.
NOTE: This is not (presently) a common core extension and is not loaded automatically when using require 'facets'
. – TODO: Does Array#median belong in a math-oriented library? ++
12 13 14 |
# File 'lib/core-uncommon/facets/array/median.rb', line 12 def median percentile(50) end |
#merge!(other) ⇒ Object
In place #merge.
a = [1,2]
a.merge! [2,3]
a #=> [1,2,3]
CREDIT: Trans
11 12 13 |
# File 'lib/core/facets/array/merge.rb', line 11 def merge!( other ) self.replace(self.merge(other)) end |
#mode ⇒ Object
In Statistics mode is the value that occurs most frequently in a given set of data. This method returns an array in case their is a tie.
[:a, :b, :c, :b, :d].mode #=> [:b]
[:a, :b, :c, :b, :a].mode #=> [:a, :b]
Returns an Array of most common elements.
CREDIT: Robert Klemme
14 15 16 17 18 19 |
# File 'lib/core/facets/array/mode.rb', line 14 def mode max = 0 c = Hash.new 0 each {|x| cc = c[x] += 1; max = cc if cc > max} c.select {|k,v| v == max}.map {|k,v| k} end |
#nonuniq ⇒ Object Also known as: duplicates
Returns a list of non-unique elements
[1,1,2,2,3,4,5].nonuniq #=> [1,2]
CREDIT: Martin DeMello
9 10 11 12 13 14 15 16 17 |
# File 'lib/core/facets/array/nonuniq.rb', line 9 def nonuniq h1 = {} h2 = {} each {|i| h2[i] = true if h1[i] h1[i] = true } h2.keys end |
#nonuniq! ⇒ Object
20 21 22 23 24 25 26 27 28 |
# File 'lib/core/facets/array/nonuniq.rb', line 20 def nonuniq! h1 = {} h2 = {} each {|i| h2[i] = true if h1[i] h1[i] = true } self.replace(h2.keys) end |
#not_empty? ⇒ Boolean
Not empty?
[].not_empty? #=> false
[1,2].not_empty? #=> true
8 9 10 |
# File 'lib/core/facets/array/not_empty.rb', line 8 def not_empty? !empty? end |
#object_state(data = nil) ⇒ Object
47 48 49 |
# File 'lib/core/facets/object/object_state.rb', line 47 def object_state(data=nil) data ? replace(data) : dup end |
#only ⇒ Object
Returns the only element in the array. Raises an IndexError if the array’s size is not 1.
[5].only # => 5
expect IndexError do
[1,2,3].only
end
expect IndexError do
[].only
end
CREDIT: Gavin Sinclair, Noah Gibbs
18 19 20 21 22 23 |
# File 'lib/core/facets/array/only.rb', line 18 def only unless size == 1 raise IndexError, "Array#only called on non-single-element array" end first end |
#pad(len, val = nil) ⇒ Object
Pad an array with a given value
up to a given length
.
[0,1,2].pad(6,"a") #=> [0,1,2,"a","a","a"]
If length
is a negative number padding will be added to the beginning of the array.
[0,1,2].pad(-6,"a") #=> ["a","a","a",0,1,2]
CREDIT: Richard Laugesen
14 15 16 17 18 19 20 21 |
# File 'lib/core/facets/array/pad.rb', line 14 def pad(len, val=nil) return dup if self.size >= len.abs if len < 0 Array.new((len+size).abs,val) + self else self + Array.new(len-size,val) end end |
#pad!(len, val = nil) ⇒ Object
Like #pad but changes the array in place.
a = [0,1,2]
a.pad!(6,"x")
a #=> [0,1,2,"x","x","x"]
CREDIT: Richard Laugesen
31 32 33 34 35 36 37 38 |
# File 'lib/core/facets/array/pad.rb', line 31 def pad!(len, val=nil) return self if self.size >= len.abs if len < 0 replace Array.new((len+size).abs,val) + self else concat Array.new(len-size,val) end end |
#peek(i = 0) ⇒ Object
Peek at the top of the stack (the end of the array).
a = [1, 2, 3]
a.peek #=> 3
a #=> [1, 2, 3]
Or provide an index to inspect the array from back to front.
14 15 16 17 |
# File 'lib/core/facets/array/pull.rb', line 14 def peek(i=0) i = -(i + 1) fetch(i) end |
#percentile(p) ⇒ Object
Returns the percentile value for percentile p; nil if array is empty.
p
should be expressed as an integer; percentile(90)
returns the 90th percentile of the array.
Algorithm from NIST
NOTE: This is not (presently) a common core extension and is not loaded automatically when using require 'facets'
.
CREDT: ?
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/core-uncommon/facets/array/percentile.rb', line 15 def percentile(p) sorted_array = self.sort rank = (p.to_f / 100) * (self.length + 1) if self.length == 0 return nil elsif rank.to_i == rank #fractional_part? sample_0 = sorted_array[rank.truncate - 1] sample_1 = sorted_array[rank.truncate] fractional_part = rank.abs.modulo(1) return (fractional_part * (sample_1 - sample_0)) + sample_0 else return sorted_array[rank.to_i - 1] end end |
#permutation(n = size) ⇒ Object
Permutation provids the possible orders of an enumerable. Each is indexed by a permutation number. The maximum number of arrangements is the factorial of the size of the array.
[1,2].permutation(2).to_a #=> [[1,2], [2,1]]
CREDIT: Shin-ichiro Hara
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/core/facets/array/permutation.rb', line 13 def permutation(n=size) if size < n or n < 0 elsif n == 0 yield([]) else self[1..-1].permutation(n - 1) do |x| (0...n).each do |i| yield(x[0...i] + [first] + x[i..-1]) end end self[1..-1].permutation(n) do |x| yield(x) end end end |
#poke(x, i = 0) ⇒ Object
Put an object on the bottom of the stack (front of the array).
a = [2, 3]
a.poke(1)
a #=> [1, 2, 3]
Or supply an index and #poke works like #insert.
26 27 28 |
# File 'lib/core/facets/array/pull.rb', line 26 def poke(x, i=0) insert(i,x) end |
#power_set ⇒ Object
20 21 22 23 24 25 26 27 28 29 |
# File 'lib/standard/facets/set.rb', line 20 def power_set if empty? [self] else subset = dup value = [ subset.pop ] subsubs = subset.power_set subsubs.concat( subsubs.map{ |subset| subset + value } ) end end |
#probability ⇒ Object
Generates a hash mapping each unique element in the array to the relative frequency, i.e. the probablity, of it appearence.
[:a, :b, :c, :c].probability #=> {:a=> 0.25, :b=>0.25, :c=>0.5}
CREDIT: Brian Schröder
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/core/facets/array/probability.rb', line 10 def probability probs = Hash.new(0.0) size = 0.0 each do |e| probs[e] += 1.0 size += 1.0 end probs.keys.each{ |e| probs[e] /= size } probs end |
#product(*enums) ⇒ Object Also known as: **
Provides the cartesian product of two or more arrays.
a = [1,2].product([4,5])
a #=> [[1, 4],[1, 5],[2, 4],[2, 5]]
CREDIT: Thomas Hafner
12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/core/facets/array/product.rb', line 12 def product(*enums) enums.unshift self result = [[]] while [] != enums t, result = result, [] b, *enums = enums t.each do |a| b.each do |n| result << a + [n] end end end result end |
#recurse(*types) {|a| ... } ⇒ Object
Apply a block to array, and recursively apply that block to each sub-array or types
.
arr = ["a", ["b", "c", nil], nil]
arr.recurse{ |a| a.compact! }
#=> ["a", ["b", "c"]]
10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/core/facets/array/recurse.rb', line 10 def recurse(*types, &block) types = [self.class] if types.empty? a = inject([]) do |array, value| case value when *types array << value.recurse(*types, &block) else array << value end array end yield a end |
#recurse!(&block) ⇒ Object
In place form of #recurse.
25 26 27 |
# File 'lib/core/facets/array/recurse.rb', line 25 def recurse!(&block) replace(recurse(&block)) end |
#recursively(*types, &block) ⇒ Object
Apply a method to array, and recursively apply that method to each sub-array or types
.
arr = ["a", ["b", "c"]]
arr.recursively.map{ |v| v.to_sym }
#=> [:a, [:b, :c]]
By default the sub-types are passed thru uneffected. Passing a block to #recursively changes this.
arr = ["a", ["b", "c"]]
arr.recursively{ |a| a.reverse }.map{ |v| v.to_sym }
#=> [:a, [:c, :b]]
TODO: Return Enumerator if no yld
block is given ?
21 22 23 |
# File 'lib/core/facets/array/recursively.rb', line 21 def recursively(*types, &block) Recursor.new(self, *types, &block) end |
#rotate(n = 1) ⇒ Object
Rotates an array’s elements from back to front n times.
[1,2,3].rotate #=> [2,3,1]
[2,3,1].rotate #=> [3,1,2]
[3,1,2].rotate #=> [1,2,3]
[1,2,3].rotate(3) #=> [1,2,3]
A negative parameter reverses the order from front to back.
[1,2,3].rotate(-1) #=> [3,1,2]
CREDIT: Florian Gross, Thomas Sawyer
19 20 21 |
# File 'lib/core/facets/array/rotate.rb', line 19 def rotate(n=1) self.dup.rotate!(n) end |
#rotate!(n = 1) ⇒ Object
Same as #rotate, but acts in place.
a = [1,2,3]
a.rotate!
a #=> [2,3,1]
CREDIT: Florian Gross, Thomas Sawyer
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/core/facets/array/rotate.rb', line 35 def rotate!(n=1) n = n.to_int return self if (n == 0 or self.empty?) if n < 0 n.abs.times{ self.unshift( self.pop ) } else n.abs.times{ self.push( self.shift ) } end self end |
#select! ⇒ Object
As with #select but modifies the Array in place.
a = [1,2,3,4,5,6,7,8,9,10]
a.select!{ |e| e % 2 == 0 }
a #=> [2,4,6,8,10]
CREDIT: Gavin Sinclair
13 14 15 |
# File 'lib/core/facets/array/select.rb', line 13 def select! # :yield: reject!{ |e| not yield(e) } end |
#shelljoin ⇒ Object
78 79 80 |
# File 'lib/standard/facets/shellwords.rb', line 78 def shelljoin Shellwords.shelljoin(shellwords) end |
#shellwords ⇒ Object
Convert an array into command line parameters. The array is accepted in the format of Ruby method arguments –ie. [arg1, arg2, …, hash]
71 72 73 74 75 |
# File 'lib/standard/facets/shellwords.rb', line 71 def shellwords opts, args = *flatten.partition{ |e| Hash === e } opts = opts.inject({}){ |m,h| m.update(h); m } opts.shellwords + args end |
#splice(*args) ⇒ Object
Splice acts a combination of #slice! and #store. If two arguments are given it calls #store. If a single argument is given it calls slice!.
a = [1,2,3]
a.splice(1) #=> 2
a #=> [1,3]
a = [1,2,3]
a.splice(1,4) #=> 4
a #=>[1,4,3]
CREDIT: Trans
19 20 21 22 23 24 25 |
# File 'lib/core/facets/array/splice.rb', line 19 def splice(*args) if args.size == 1 slice!(*args) else store(*args) end end |
#split(pattern) ⇒ Object
Split on matching pattern. Unlike #divide this does not include matching elements.
['a1','a2','b1','a3','b2','a4'].split(/^b/)
#=> [['a1','a2'],['a3'],['a4']]
CREDIT: Trans
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/core/facets/array/split.rb', line 10 def split(pattern) memo = [] sect = [] each do |obj| if pattern === obj memo << sect sect = [] else sect << obj end end memo << sect memo.pop while memo.last == [] memo end |
#thru(from, to = nil) ⇒ Object
Fetch values from a start index thru an end index.
[1,2,3,4,5].thru(0,2) #=> [1,2,3]
[1,2,3,4,5].thru(2,4) #=> [3,4,5]
[1,2,3,4,5].thru(2) #=> [1,2,3]
[1,2,3,4,5].thru(4) #=> [1,2,3,4,5]
20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/core/facets/array/from.rb', line 20 def thru(from, to=nil) from, to = 0, from unless to to = size - 1 if to >= size a = [] i = from while i <= to a << self[i] i += 1 end a end |
#to_b ⇒ Object
Boolean conversion for not empty?
110 111 112 |
# File 'lib/core/facets/boolean.rb', line 110 def to_b ! self.empty? end |
#to_h(mode = nil) ⇒ Object
Converts an array into a hash. Converting an array into a hash is not a one-to-one conversion, for this reason #to_h examines at the array being converted and then dispatches the conversion to the most sutiable specialized function. There are three possiblities for this.
If the array is a collection of perfect pairs, like that which Hash#to_a generates, then conversion is handled by #to_h_flat.
a = [ [:a,1], [:b,2] ]
a.to_h #=> { :a=>1, :b=>2 }
If the array contains only arrays, but are not perfect pairs, then #to_h_multi is called.
a = [ [:a,1,2], [:b,2], [:c], [:d] ]
a.to_h #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
If the array contians objects other then arrays then the #to_h_splat method is called.
a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
a.to_h #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }
Finally, a particular dispatch can be forced by specifying the mode
of conversion, eg. :multi
, :splat
, :flat
, :assoc
, etc.
Setting mode
to true
is the same as setting it :multi
. This has been left in for backward compatability.
NOTE: The use of a values
parameter has been deprecated because that functionality is as simple as …
array1.zip(array2).to_h
CREDIT: Robert Klemme, Trans
– The True
option in the case statement provides some backward compatability with the previous versions of this method. ++
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/core/facets/to_hash.rb', line 51 def to_h(mode=nil) case mode when :splat return to_h_splat when :flat return to_h_flat when :multi, true return to_h_multi when :assoc return to_h_assoc else return to_h_auto end end |
#to_h_assoc ⇒ Object
When a mixed or multi-element accociative array is used, the result is as follows:
a = [ [:a,1,2], [:b,2], [:c], :d ]
a.to_h #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
If the first entry of any subelements are the same, then the value will be set to the last occuring value.
a = [ :x, [:x], [:x,1,2], [:x,3], [:x,4] ]
a.to_h_assoc #=> { :x=>[4] }
157 158 159 160 161 162 163 |
# File 'lib/core/facets/to_hash.rb', line 157 def to_h_assoc h = {} each do |k,*v| h[k] = v end h end |
#to_h_auto ⇒ Object
Converts an array into a hash. Converting an array into a hash is not a one-to-one conversion, for this reason #to_h examines at the array being converted and then dispatches the conversion to the most sutiable specialized function. There are three possiblities for this.
If the array is a collection of perfect pairs, like that which Hash#to_a generates, then conversion is handled by #to_h_flat.
a = [ [:a,1], [:b,2] ]
a.to_h_auto #=> { :a=>1, :b=>2 }
If the array contains only arrays, but are not perfect pairs, then #to_h_multi is called.
a = [ [:a,1,2], [:b,2], [:c], [:d] ]
a.to_h_auto #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
If the array contians objects other then arrays then the #to_h_splat method is called.
a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
a.to_h_auto #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/core/facets/to_hash.rb', line 91 def to_h_auto pairs = true mixed = false each do |e| case e when Array pairs = false if e.size > 2 else mixed = true end end if mixed to_h_splat elsif pairs to_h_flat else to_h_multi end end |
#to_h_flat ⇒ Object
This is equivalent to Hash, but it will pad the array with a nil
object if there are not an even number of elements.
a = [:a,1,[:b,2,:c]]
a.to_h_flat #=> { :a=>1, :b=>2, :c=>nil }
133 134 135 136 137 |
# File 'lib/core/facets/to_hash.rb', line 133 def to_h_flat a = flatten a << nil if a.size % 2 == 1 Hash[*a] end |
#to_h_multi ⇒ Object
When a mixed or multi-element accociative array is used, the result is as follows:
a = [ [:a,1,2], [:b,2], [:c], :d ]
a.to_h #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }
If the first entry of the subelements is the same, then the values will be merged using #concat.
a = [ [:a,1,2], [:a,3], [:a,4], [:a], :a ]
a.to_h_multi #=> { :a=>[1,2,3,4] }
177 178 179 180 181 182 183 184 |
# File 'lib/core/facets/to_hash.rb', line 177 def to_h_multi h = {} each do |k,*v| h[k] ||= [] h[k].concat(v) end h end |
#to_h_splat ⇒ Object
This is equivalent to Hash, but it will pad the array with a nil
object if there are not an even number of elements.
a = [:a,1,:b,2,:c]
a.to_h_splat #=> { :a=>1, :b=>2, :c=>nil }
120 121 122 123 124 |
# File 'lib/core/facets/to_hash.rb', line 120 def to_h_splat a = dup a << nil if a.size % 2 == 1 Hash[*a] end |
#to_t ⇒ Object
Convert an array into a tuple.
276 277 278 |
# File 'lib/supplemental/facets/tuple.rb', line 276 def to_t Tuple.cast_from_array( self ) end |
#traverse(&block) ⇒ Object
Returns a new array created by traversing the array and its sub-arrays, executing the given block on the elements.
h = ["A", "B", ["X", "Y"]]
g = h.traverse{ |e| e.downcase }
g #=> ["a", "b", ["x", "y"]]
This is the same as recursive.map
and will likely be deprecated in the future because of it.
CREDIT: Trans
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/core/facets/array/traverse.rb', line 16 def traverse(&block) if block_given? map do |e| if e.respond_to?(:to_ary) e.to_ary.traverse(&block) else block.call(e) end end else to_enum(:traverse) end end |
#traverse!(&block) ⇒ Object
Like #recursive_map, but will change the array in place.
h = ["A", "B", ["X", "Y"]]
h.traverse!{ |e| e.downcase }
h #=> ["a", "b", ["x", "y"]]
CREDIT: Trans
39 40 41 |
# File 'lib/core/facets/array/traverse.rb', line 39 def traverse!(&block) replace(traverse(&block)) end |
#uniq_by! ⇒ Object
Like #uniq, but determines uniqueness based on a given block.
a = (-5..5).to_a
a.uniq_by!{ |i| i*i }
a #=> [-5, -4, -3, -2, -1, 0]
As can be seen in the example, order is significant.
10 11 12 13 |
# File 'lib/core/facets/array/uniq_by.rb', line 10 def uniq_by! #:yield: h = {} replace( inject([]){|a,x| h[yield(x)] ||= a << x} ) end |