Class: Array
- Includes:
- Indexable, Random::ArrayExtensions
- Defined in:
- lib/standard/facets/pathname/to_path.rb,
lib/core/facets/boolean.rb,
lib/core/facets/array/pad.rb,
lib/core/facets/array/zip.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/core/facets/array/span.rb,
lib/core/facets/array/step.rb,
lib/core/facets/array/to_h.rb,
lib/core/facets/array/merge.rb,
lib/core/facets/array/occur.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/median.rb,
lib/core/facets/array/op_pow.rb,
lib/core/facets/array/splice.rb,
lib/core/facets/kernel/blank.rb,
lib/core/facets/array/arrange.rb,
lib/core/facets/array/average.rb,
lib/core/facets/array/conjoin.rb,
lib/core/facets/array/entropy.rb,
lib/core/facets/array/missing.rb,
lib/core/facets/array/nonuniq.rb,
lib/core/facets/array/recurse.rb,
lib/core/facets/array/squeeze.rb,
lib/core/facets/array/uniq_by.rb,
lib/core/facets/array/collapse.rb,
lib/core/facets/array/contains.rb,
lib/core/facets/array/split_at.rb,
lib/core/facets/array/traverse.rb,
lib/core/facets/array/variance.rb,
lib/core/facets/array/each_pair.rb,
lib/core/facets/array/indexable.rb,
lib/core/facets/array/not_empty.rb,
lib/core/facets/array/duplicates.rb,
lib/core/facets/array/each_value.rb,
lib/core/facets/array/occurrence.rb,
lib/core/facets/array/commonality.rb,
lib/core/facets/array/probability.rb,
lib/core/facets/array/recursively.rb,
lib/core/facets/array/each_overlap.rb,
lib/core/facets/array/intersection.rb,
lib/core/facets/array/delete_unless.rb,
lib/core/facets/array/delete_values.rb,
lib/core/facets/array/reject_values.rb,
lib/core/facets/object/object_state.rb,
lib/core/facets/array/extract_options.rb,
lib/core/facets/array/standard_deviation.rb,
lib/core/facets/array/unique_permutation.rb,
lib/standard/facets/set.rb,
lib/standard/facets/tuple.rb,
lib/standard/facets/random.rb,
lib/standard/facets/shellwords.rb
Overview
Class Method Summary collapse
-
.zip(*arrays) ⇒ Object
Class level rendition of Array#zip.
Instance Method Summary collapse
-
#after(value) ⇒ Object
Returns the value after the given value.
-
#arrange ⇒ Object
(also: #rangify)
The ‘arrange` method produces appropriate ranges from the objects in the array.
-
#average ⇒ Object
Calculate the average of an array of numbers.
-
#before(value) ⇒ Object
Returns the value previous to the given value.
-
#collapse ⇒ Object
Simplify an array by flattening it then compacting it.
- #collapse! ⇒ Object
-
#commonality(&block) ⇒ Object
(also: #collisions)
Get a list of all items that have something in common 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.
-
#duplicates(min = 2) ⇒ Object
Return list of duplicate elements.
-
#each_overlap(slice_size, overlap) ⇒ Object
Iterate over each slice where the last n values of a preceding slice overlap with the first n values of the following slice.
-
#each_pair ⇒ Object
Iterate over index and value.
-
#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(index) ⇒ Object
Returns elements from ‘index` until the 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).
-
#intersection ⇒ Object
CREDIT: monocle.
-
#median(offset = 0) ⇒ Object
Determines the sorted middle element.
-
#merge!(other) ⇒ Object
In place #merge.
-
#missing ⇒ Object
CREDIT: monocle.
-
#mode ⇒ Object
In Statistics.
-
#nonuniq ⇒ Object
Returns a list of non-unique elements.
-
#nonuniq! ⇒ Object
Same as ‘#nonuniq` but acts in place.
-
#not_empty? ⇒ Boolean
Not empty?.
- #object_state(data = nil) ⇒ Object
-
#occur(n = nil) ⇒ Object
(also: #occurs)
Returns a list of elements that occur
n
times. -
#occurrence ⇒ Object
Create a hash of each uniq element of the array and how many time each appears.
-
#only ⇒ Object
Returns the only element in the array.
-
#only? ⇒ Boolean
Does this Array have only one element?.
-
#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).
-
#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.
-
#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 given
types
. -
#reject_values(*values) ⇒ Object
Non-destructive form of ‘Array#delete_values`.
- #shelljoin ⇒ Object
-
#shellwords ⇒ Object
Convert an array into command line parameters.
-
#span ⇒ Object
Public: Split an array in two using a predicate.
-
#splice(*args) ⇒ Object
Splice acts as a combination of #slice! and #store.
-
#split(pattern) ⇒ Object
Split on matching pattern.
-
#split_at(*args, &block) ⇒ Object
Split on matching pattern.
-
#squeeze!(*limited_to) ⇒ Object
Destructive version of Enumerable#squeeze.
-
#standard_deviation ⇒ Object
(also: #sd)
Calculate the standard_deviation of an array of numbers.
-
#step(n) ⇒ Object
Iterate over every nth element of an array.
-
#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 ⇒ Object
Convert an associative array to a Hash.
-
#to_path ⇒ Object
Convert array to Pathname instance.
-
#to_t ⇒ Object
Convert an array into a tuple.
-
#traverse(&block) ⇒ Object
Construct 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.
-
#unique_permutation(n = self.size) {|a[0,n]| ... } ⇒ Object
Enumerates permutation of Array.
-
#variance ⇒ Object
Calculate the variance of an array of numbers.
Methods included from Random::ArrayExtensions
#at_rand, #at_rand!, #pick, #pick!, #rand_index, #rand_subarrays, #rand_subset, #shuffle, #shuffle!
Methods included from Indexable
#body, #ends, #first, #first=, #foot, #head, #index, #last, #last=, #mid, #middle, #pos, #range, #tail
Class Method Details
.zip(*arrays) ⇒ Object
Class level rendition of Array#zip.
arrays - List of arrays to zip. [Array<Array>]
Example:
Array.zip([1,2],[3,4]]
#=> [[1,3],[2,4]]
Returns arranged array of arrays. [Array<Array>]
Returns an empty array if no arguments are given. [Array]
16 17 18 19 |
# File 'lib/core/facets/array/zip.rb', line 16 def self.zip(*arrays) return [] if arrays.empty? return arrays[0].zip(*arrays[1..-1]) end |
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.
Examples
sequence = ['a', 'b', 'c']
sequence.after('a') #=> 'b'
sequence.after('b') #=> 'c'
sequence.after('c') #=> 'a'
sequence.after('d') #=> nil
CREDIT: Tyler Rick
35 36 37 38 |
# File 'lib/core/facets/array/before.rb', line 35 def after(value) return nil unless include? value self[(index(value).to_i + 1) % length] end |
#arrange ⇒ Object Also known as: rangify
The ‘arrange` method produces appropriate ranges from the objects in the array.
Examples
[1,2,3,6,7,8].arrange #=> [1..3, 6..8]
[10..15, 16..20, 21, 22].arrange #=> [10..22]
Assumes inclusive ranges (ie. 1..4) and range.first <= range.last.
Works with integers, dates and strings. However, all the objects in the array must be of the same class.
CREDIT: monocle
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/core/facets/array/arrange.rb', line 18 def arrange array = uniq.sort_by { |e| Range === e ? e.first : e } array.inject([]) do |c, value| unless c.empty? last = c.last last_value = (Range === last ? last.last : last) current_value = (Range === value ? value.first : value) if (last_value.succ <=> current_value) == -1 c << value else first = (Range === last ? last.first : last) second = [Range === last ? last.last : last, Range === value ? value.last : value].max c[-1] = [first..second] c.flatten! end else c << value end end end |
#average ⇒ Object
Calculate the average of an array of numbers
Examples
[].average #=> nil
[1, 2, 3].average #=> 2
[3, 12, 57, 85, 15, 89, 33, 7, 22, 54].average #=> 37.7
11 12 13 14 |
# File 'lib/core/facets/array/average.rb', line 11 def average return nil if empty? self.reduce(:+)/length.to_f 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
17 18 19 20 |
# File 'lib/core/facets/array/before.rb', line 17 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.
Examples
[1,[2,nil,[3]],nil,4].collapse #=> [1,2,3,4]
9 10 11 |
# File 'lib/core/facets/array/collapse.rb', line 9 def collapse flatten.compact end |
#collapse! ⇒ Object
13 14 15 |
# File 'lib/core/facets/array/collapse.rb', line 13 def collapse! flatten!.compact! end |
#commonality(&block) ⇒ Object Also known as: collisions
Get a list of all items that have something in common in terms of the supplied block. If no block is given objects are considered to be in common if they return the same value for Object#hash and if obj1 == obj2.
This can be useful, for instance, in determining all persons that share their last name with another person.
persons.commonality { |person| person.last_name }
The method is similar to #group_by which is a standard Ruby method as of 1.9. To get effectively the same results with #group_by use ‘select{ |k,v| v.size > 1 }`.
[1, 2, 2, 3, 4, 4].group_by{ |e| e }.select{ |k,v| v.size > 1 }
#=> { 2 => [2, 2], 4 => [4, 4] }
Examples
[1, 2, 2, 3, 4, 4].commonality #=> { 2 => [2, 2], 4 => [4, 4] }
["foo", "bar", "baz"].commonality { |str| str[0] }
#=> { 'b' => ["bar", "baz"] }
Returns [Hash] mapping common attribute to those elements.
CREDIT: Florian Gross
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/core/facets/array/commonality.rb', line 29 def commonality(&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 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']]
['a1','b1','a2','b2'].divide(/^b/)
#=> [['a1',['b1','a2'],[]'b2']]
['a1','b1','a2','b2'].divide(/^c/)
#=> [['a1','b1','a2','b2']]
CREDIT: Trans
16 17 18 19 20 21 22 23 24 |
# File 'lib/core/facets/array/divide.rb', line 16 def divide(pattern) memo = [] memo.push [] unless pattern === first each do |obj| memo.push [] if pattern === obj memo.last << obj end memo end |
#duplicates(min = 2) ⇒ Object
Return list of duplicate elements.
min - The minimum number of duplication necessary for inclusion. [Integer]
Examples:
[1,1,2,3].duplicates #=> [1]
[1,1,2,3,2,4,5,4,2].duplicates(3) #=> [2]
CREDIT: Rebort Dober (current implementation) CREDIT: Thibaut Barrère
16 17 18 19 20 21 22 |
# File 'lib/core/facets/array/duplicates.rb', line 16 def duplicates(min=2) h = Hash.new( 0 ) each {|i| h[i] += 1 } h.delete_if{|_,v| v < min}.keys end |
#each_overlap(slice_size, overlap) ⇒ Object
Iterate over each slice where the last n values of a preceding slice overlap with the first n values of the following slice. The value of n is specified by the second ‘overlap` argument.
a, r = [1,2,3,4,5], []
a.each_overlap(2,1) { |x,y| r << [x,y] }
r # => [[1,2],[2,3],[3,4],[4,5]]
Returns nothing.
13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/core/facets/array/each_overlap.rb', line 13 def each_overlap(slice_size, overlap) if block_given? i = 0 while i + slice_size <= length yield slice(i...i+slice_size) i += (slice_size - overlap) end else to_enum(:each_overlap, slice_size, overlap) end end |
#each_pair ⇒ Object
Iterate over index and value. The intention of this method is to provide polymorphism with Hash.
6 7 8 |
# File 'lib/core/facets/array/each_pair.rb', line 6 def each_pair #:yield: each_with_index {|e, i| yield(i,e) } 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(index) ⇒ Object
Returns elements from ‘index` until the end.
%w{W o r l d}.from(3) #=> ["l", "d"]
%w{W o r l d}.from(9) #=> []
8 9 10 11 |
# File 'lib/core/facets/array/from.rb', line 8 def from(index) return [] if index >= size self[index..-1] 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 |
#intersection ⇒ Object
CREDIT: monocle
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/core/facets/array/intersection.rb', line 7 def intersection array = uniq.sort_by { |e| Range === e ? e.first : e } array.inject() do |c, e| f = (Range === c ? c.last : c) v = (Range === e ? e.first : e) case f <=> v when -1 then return nil when 0 then f else if Range === e v..([f, e.last].min) else v end end end end |
#median(offset = 0) ⇒ Object
Determines the sorted middle element.
a = %w{a a b b c c c}
a.median #=> "b"
When there are an even number of elements, the greater of the two middle elements is given.
a = %w{a a b b c c c d}
a.median #=> "c"
An offset can be supplied to get an element relative to the middle.
a = %w{a a b b c c c d}
a.median(-1) #=> "b"
The the array is empty, nil
is returned.
23 24 25 26 27 28 29 30 |
# File 'lib/core/facets/array/median.rb', line 23 def median(offset=0) return nil if self.size == 0 tmp = self.sort mid = (tmp.size / 2).to_i + offset tmp[mid] 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 |
#missing ⇒ Object
CREDIT: monocle
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/core/facets/array/missing.rb', line 13 def missing missing, array = [], arrange i, length = 0, array.size - 1 while i < length x0 = array[i] x1 = array[i+1] c = (Range === x0 ? x0.last : x0) n = (Range === x1 ? x1.first : x1) missing << ( c.succ.succ == n ? c.succ : ((c.succ)..(n.pred)) ) i += 1 end return missing 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 there 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.
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
Returns a list of non-unique elements.
Examples
[1,1,2,2,3,4,5].nonuniq #=> [1,2]
CREDIT: Martin DeMello
11 12 13 14 15 16 17 18 19 |
# File 'lib/core/facets/array/nonuniq.rb', line 11 def nonuniq h1 = {} h2 = {} each {|i| h2[i] = true if h1[i] h1[i] = true } h2.keys end |
#nonuniq! ⇒ Object
Same as ‘#nonuniq` but acts in place.
23 24 25 |
# File 'lib/core/facets/array/nonuniq.rb', line 23 def nonuniq! self.replace(self.nonuniq) 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 |
#occur(n = nil) ⇒ Object Also known as: occurs
Returns a list of elements that occur n
times.
If n
is a Range then returns elements that occur a number of time within the range.
Examples
[0,1,1,1,3,0,1,2,4].occur(3) #=> [1]
[0,1,1,1,3,0,1,2,4].occur(2..4) #=> [0,1]
Returns [Array] of reoccurring elements.
CREDIT: Robert Dober
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/core/facets/array/occur.rb', line 18 def occur(n=nil) #:yield: h = Hash.new(0) each do |i| h[i] += 1 end case n when nil h.delete_if{ |_,v| ! yield(v) }.keys when Range h.delete_if{ |_,v| ! n.include?(v) }.keys else h.delete_if{|_,v| v != n}.keys end end |
#occurrence ⇒ Object
Create a hash of each uniq element of the array and how many time each appears.
Examples
[:a,:a,:b,:c,:c,:c].occurrence
#=> { :a => 2, :b => 1, :c => 3 }
[2,2,3,4,4,4].occurrence{|i| i % 2}
#=> { 0 => 5, 1 => 1 }
14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/core/facets/array/occurrence.rb', line 14 def occurrence h = Hash.new(0) if block_given? each do |e| h[yield(e)] += 1 end else each do |e| h[e] += 1 end end h 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, "not the only element of array" end first end |
#only? ⇒ Boolean
Does this Array have only one element?
TODO: While clearly this goes along with the regular #only method, the name doesn’t seem quite right. Perhaps rename to #lonely.
CREDIT: Lavir the Whiolet
32 33 34 |
# File 'lib/core/facets/array/only.rb', line 32 def only? size == 1 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 |
#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
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/standard/facets/set.rb', line 24 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 probability, of it appearance.
[: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 |
#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 given types
.
By default the sub-types are passed through unaffected. Passing a block to #recursively can be used to change this.
types - List of class types to recurse. [Array<Class>] block - Optional filter procedure to apply on each recursion.
Examples
arr = ["a", ["b", "c"]]
arr.recursively.map{ |v| v.to_sym }
#=> [:a, [:b, :c]]
arr = ["a", ["b", "c"]]
arr.recursively{ |a| a.reverse }.map{ |v| v.to_sym }
#=> [:a, [:c, :b]]
Returns [Recursor].
27 28 29 |
# File 'lib/core/facets/array/recursively.rb', line 27 def recursively(*types, &block) Recursor.new(self, *types, &block) end |
#reject_values(*values) ⇒ Object
Non-destructive form of ‘Array#delete_values`. Unlike `delete_values` this method returns a new array.
values - List of array elements to reject.
Examples
[1,2,3,4,5].reject_values(2,4) # => [1,3,5]
Returns [Array]
CREDIT: Sean Mackesey
16 17 18 |
# File 'lib/core/facets/array/reject_values.rb', line 16 def reject_values(*values) reject { |x| values.include?(x) } end |
#shelljoin ⇒ Object
81 82 83 |
# File 'lib/standard/facets/shellwords.rb', line 81 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]
74 75 76 77 78 |
# File 'lib/standard/facets/shellwords.rb', line 74 def shellwords opts, args = *flatten.partition{ |e| Hash === e } opts = opts.inject({}){ |m,h| m.update(h); m } opts.shellwords + args end |
#span ⇒ Object
Public: Split an array in two using a predicate
Yields each element of the array.
Examples
%w(The quick brown fox).span { |word| word.length < 4 }
#=> [['The'], ['quick', 'brown', 'fox']]
[1, 1, 2, 3, 5, 8, 13, 21, 34].span(&:odd?)
#=> [[1, 1], [2, 3, 5, 8, 13, 21, 34]]
Returns a 2-tuple of arrays, the first element being the longest prefix for which the block evaluates to true, the second element being the rest of the array.
17 18 19 20 21 22 23 |
# File 'lib/core/facets/array/span.rb', line 17 def span # This implementation is another way of saying # `[take_while(&:block), drop_while(&:block)]` index = find_index { |e| !yield e } return [dup, []] if index.nil? [take(index), drop(index)] end |
#splice(*args) ⇒ Object
Splice acts as a combination of #slice! and #store. If two arguments are given it calls #store. If a single argument is given it calls slice!.
Examples
a = [1,2,3]
a.splice(1) #=> 2
a #=> [1,3]
a = [1,2,3]
a.splice(1,4) #=> 4
a #=> [1,4,3]
Returns [Array].
CREDIT: Trans
23 24 25 26 27 28 29 |
# File 'lib/core/facets/array/splice.rb', line 23 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.
Examples
['a1','a2','b1','a3','b2','a4'].split(/^b/)
#=> [['a1','a2'],['a3'],['a4']]
Returns list of split-up arrays. [Array<Array>]
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/core/facets/array/split.rb', line 13 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 |
#split_at(*args, &block) ⇒ Object
Split on matching pattern. Breaks the array into [before, middle, after] segments. Uses Array#index to find the middle element.
Examples
['a1','a2','b1','a3','b2','a4'].split('b1')
#=> [['a1','a2'],b1,['a3','b2','a4']]
['a1','a2','b1','a3','b2','a4'].split('foo')
#=> [[],nil,[]]
Returns list of split-up arrays. [Tuple<Array,Object,Array>]
16 17 18 19 20 21 22 |
# File 'lib/core/facets/array/split_at.rb', line 16 def split_at(*args, &block) if middle = index(*args, &block) [self[0...middle], self[middle], self[middle+1..-1]] else [[], nil, []] end end |
#squeeze!(*limited_to) ⇒ Object
Destructive version of Enumerable#squeeze.
a = [1,2,2,3,3,2,1]
a.squeeze!
a #=> [1,2,3,2,1]
a = [1,2,2,3,3,2,1]
a.squeeze!(*[3])
a #=> [1,2,2,3,2,1]
Returns the receiver. [Array]
CREDIT: T. Yamada
19 20 21 |
# File 'lib/core/facets/array/squeeze.rb', line 19 def squeeze!(*limited_to) replace(squeeze(*limited_to)) end |
#standard_deviation ⇒ Object Also known as: sd
Calculate the standard_deviation of an array of numbers
Examples
[].standard_deviation #=> nil
[1, 2, 3].standard_deviation #=> 0.816496580927726
[96, 35, 72, 30, 75, 33, 68, 13, 49, 71].standard_deviation #=> 24.69331893448104
[36, -67, -17, 85, -46, -64, -23, -13, 89, -47].standard_deviation #=> 54.67183918618432
[60.7829, 31.2622, 20.626, 78.8907, 61.5328].standard_deviation #=> 21.428815505053002
15 16 17 18 |
# File 'lib/core/facets/array/standard_deviation.rb', line 15 def standard_deviation return nil if empty? Math.sqrt(variance) end |
#step(n) ⇒ Object
Iterate over every nth element of an array.
r = []
[:a, :b, :c, :d].step(2) { |x| r << x }
r #=> [:b, :d]
Without a block it returns an Enumerator.
[:a, :b, :c, :d].step(1).to_a #=> [:a, :b, :c, :d]
[:a, :b, :c, :d].step(2).to_a #=> [:b, :d]
[:a, :b, :c, :d].step(3).to_a #=> [:c]
[:a, :b, :c, :d].step(5).to_a #=> []
CREDIT: Ryan Duryea
18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/core/facets/array/step.rb', line 18 def step(n) #:yield: if block_given? ((n - 1)...size).step(n).each do |i| yield(fetch(i)) end else Enumerator.new(size / n) do |y| ((n - 1)...self.size).step(n).each { |i| y << fetch(i) } end end end |
#thru(from, to = nil) ⇒ Object
Fetch values from a start index thru an end index.
[1,2,3,4,5].thru(2) #=> [1,2,3]
[1,2,3,4,5].thru(4) #=> [1,2,3,4,5]
[1,2,3,4,5].thru(0,2) #=> [1,2,3]
[1,2,3,4,5].thru(2,4) #=> [3,4,5]
21 22 23 24 25 |
# File 'lib/core/facets/array/from.rb', line 21 def thru(from, to=nil) from, to = 0, from unless to return [] if from >= size self[from..to] 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 ⇒ Object
Convert an associative array to a Hash.
Examples
[[:a, 1], [:b, 2]].to_h
#=> {:a=>1, :b=>2}
Returns [Hash].
12 13 14 15 16 |
# File 'lib/core/facets/array/to_h.rb', line 12 def to_h h = {} each{ |(k,v)| h[k] = v } h end |
#to_path ⇒ Object
Convert array to Pathname instance.
24 25 26 |
# File 'lib/standard/facets/pathname/to_path.rb', line 24 def to_path Pathname.new(join('/')) end |
#to_t ⇒ Object
Convert an array into a tuple.
276 277 278 |
# File 'lib/standard/facets/tuple.rb', line 276 def to_t Tuple.cast_from_array( self ) end |
#traverse(&block) ⇒ Object
Construct a new array created by traversing the array and its sub-arrays, executing the given block on the elements.
Examples
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.
Returns new array. [Array]
CREDIT: Trans
19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/core/facets/array/traverse.rb', line 19 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.
Examples:
h = ["A", "B", ["X", "Y"]]
h.traverse!{ |e| e.downcase }
h #=> ["a", "b", ["x", "y"]]
Returns self. [Array]
CREDIT: Trans
45 46 47 |
# File 'lib/core/facets/array/traverse.rb', line 45 def traverse!(&block) replace(traverse(&block)) end |
#uniq_by! ⇒ Object
Like #uniq, but determines uniqueness based on a given block. As can be seen in the following examples, order is significant.
Examples
a = (-5..5).to_a
a.uniq_by!{ |i| i*i }
a #=> [-5, -4, -3, -2, -1, 0]
a = (-5..5).to_a.reverse
a.uniq_by!{ |i| i*i }
a #=> [5, 4, 3, 2, 1, 0]
Returns [Array] of unique elements.
18 19 20 21 |
# File 'lib/core/facets/array/uniq_by.rb', line 18 def uniq_by! #:yield: h = {} replace( inject([]){|a,x| h[yield(x)] ||= a << x} ) end |
#unique_permutation(n = self.size) {|a[0,n]| ... } ⇒ Object
Enumerates permutation of Array. Unlike Array#permutation, there are no duplicates in generated permutations. Instead, elements must be comparable.
[1,1,2,2,3].unique_permutation(2).to_a
#=> [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2]]
# Note: [1,1,2,2,3].permutation(2).to_a
#=> [[1, 1], [1, 2], [1, 2], [1, 3], [1, 1], [1, 2], [1, 2], [1, 3], [2, 1], [2, 1], [2, 2], [2, 3], [2, 1], [2, 1], [2, 2], [2, 3], [3, 1], [3, 1], [3, 2], [3, 2]]
CREDIT: T. Yamada
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/core/facets/array/unique_permutation.rb', line 13 def unique_permutation(n=self.size) return to_enum(:unique_permutation,n) unless block_given? return if n<0||self.size<n a=self.sort # sort is O(nlogn), so I believe this is not so costly. (Also sort is not destructive) yield a[0,n] loop{ a=a[0,n]+a[n..-1].reverse k=(a.size-2).downto(0).find{|i|a[i]<a[i+1]} break if !k l=(a.size-1).downto(k+1).find{|i|a[k]<a[i]} a[k],a[l]=a[l],a[k] a=a[0,k+1]+a[k+1..-1].reverse yield a[0,n] } end |
#variance ⇒ Object
Calculate the variance of an array of numbers
Examples
[].variance #=> nil
[1, 2, 3].variance #=> 0.6666666666666666
[96, 35, 72, 30, 75, 33, 68, 13, 49, 71].variance #=> 609.76
[36, -67, -17, 85, -46, -64, -23, -13, 89, -47].variance #=> 2989.0099999999993
[60.7829, 31.2622, 20.626, 78.8907, 61.5328].variance #=> 459.1941339495999
15 16 17 18 |
# File 'lib/core/facets/array/variance.rb', line 15 def variance avg = average map {|n| (n - avg) ** 2 }.average end |