Class: Array
- Includes:
- Indexable, Random::ArrayExtensions
- Defined in:
- lib/standard/facets/pathname/to_path.rb,
lib/core/facets/boolean.rb,
lib/standard/facets/set.rb,
lib/core/facets/array/pad.rb,
lib/core/facets/array/zip.rb,
lib/standard/facets/tuple.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/standard/facets/random.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/remove.rb,
lib/core/facets/array/splice.rb,
lib/core/facets/kernel/blank.rb,
lib/core/facets/array/average.rb,
lib/core/facets/array/conjoin.rb,
lib/core/facets/array/entropy.rb,
lib/core/facets/array/indexes.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/standard/facets/shellwords.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/to_ranges.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/delete_first.rb,
lib/core/facets/array/each_overlap.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
Overview
Class Method Summary collapse
-
.zip(*arrays) ⇒ Object
Class level rendition of Array#zip.
Instance Method Summary collapse
-
#after(value) ⇒ Object
Returns the value next to the given value.
-
#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_first(el) ⇒ Object
Deletes first item from
selfthat is equal toobj. -
#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.
-
#duplicates!(min = 2) ⇒ Object
In-place version of #duplicates.
-
#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
indexuntil 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).
-
#indexes(*args) ⇒ Object
(also: #index_all)
Returns an array of indexes of all objects in receiver such that the object is == to obj.
-
#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
#nonuniqbut 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
ntimes. -
#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
valueup 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`.
-
#remove(other_ary) ⇒ Object
Returns a new array that is a copy of the original array, removing the first occurrence of any item that also appears in
other_ary. -
#remove!(other_ary) ⇒ Object
For each element of
other_ary, deletes the first element from self that is equal to that element (usingdelete_at, notdelete). - #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
-
#stddev ⇒ Object
(also: #sd)
Calculate the standard_deviation of an array of numbers.
-
#step(n, offset = 0) ⇒ 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_path ⇒ Object
Convert array to Pathname instance.
-
#to_ranges ⇒ Object
(also: #arrange, #rangify)
Produces an array of ranges from the values in the array.
-
#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!(&block) ⇒ 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 Indexable
#body, #ends, #first, #first=, #foot, #head, #index, #last, #last=, #mid, #middle, #pos, #range, #tail
Methods included from Random::ArrayExtensions
#at_rand, #at_rand!, #pick, #pick!, #rand_index, #rand_subarrays, #rand_subset, #sample!
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 next to the given value. The value next to 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 |
#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_first(el) ⇒ Object
Deletes first item from self that is equal to obj.
Returns the deleted item, or nil if no matching item is found.
If the optional code block is given, the result of the block is returned if the item is not found.
a = [ "a", "b", "b", "b", "c" ]
a.delete_first("b") #=> "b"
a #=> ["a", "c"]
a.delete("z") #=> nil
a.delete("z") {"not found"} #=> "not found"
14 15 16 17 18 19 |
# File 'lib/core/facets/array/delete_first.rb', line 14 def delete_first(el) i = index(el) if i delete_at(i) end 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 |
#duplicates!(min = 2) ⇒ Object
In-place version of #duplicates. Replaces the array with only its duplicate elements.
Examples:
a = [1,1,2,3,2]
a.duplicates! #=> [1,2]
a #=> [1,2]
33 34 35 |
# File 'lib/core/facets/array/duplicates.rb', line 33 def duplicates!(min=2) replace(duplicates(min)) 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 |
#indexes(*args) ⇒ Object Also known as: index_all
Returns an array of indexes of all objects in receiver such that the object is == to obj.
If a block is given instead of an argument, returns the indexes of all objects for which the block returns true.
If neither a block nor argument is given, an Enumerator for all indexes (each_index) is returned.
Returns [] if no match is found.
a = [ "a", "b", "c" ]
a.indexes("b").to_a #=> [1]
a.indexes("z").to_a #=> []
a.indexes { |x| x == "b" }.to_a #=> [1]
Like Array#index/rindex and Enumerable#find_index but returns all indexes instead of just the first/last.
See also: proposal to add Array#indexes to Ruby language: bugs.ruby-lang.org/issues/6596
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/core/facets/array/indexes.rb', line 22 def indexes(*args) case args.length when 0 if block_given? each_index.select {|i| yield(self[i]) } else each_index end when 1 other = args.first each_index.select {|i| self[i] == other } else raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0..1)" 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
13 14 15 16 |
# File 'lib/core/facets/array/nonuniq.rb', line 13 def nonuniq warn "Array#nonuniq is deprecated. Use Array#duplicates instead.", uplevel: 1 duplicates end |
#nonuniq! ⇒ Object
Same as #nonuniq but acts in place.
20 21 22 23 |
# File 'lib/core/facets/array/nonuniq.rb', line 20 def nonuniq! warn "Array#nonuniq! is deprecated. Use Array#duplicates instead.", uplevel: 1 self.replace(duplicates) 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 }
Without a block, this is equivalent to Ruby’s #tally. With a block, the block transforms the key before counting, which #tally does not support.
18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/core/facets/array/occurrence.rb', line 18 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 |
#remove(other_ary) ⇒ Object
Returns a new array that is a copy of the original array, removing the first occurrence of any item that also appears in other_ary. The order is preserved from the original array.
If there are multiple occurrences of an item in other_ary, this removes that many occurrences from self.
This is similar to ‘Array#-` and `Array#difference`, except that instead of removing all matches, it only removes as many occurrences as there are in the other_ary:
> [1, 1, 2].remove [1]
=> [1, 2]
> [1, 1, 2].remove [1, 1, 1]
=> [2]
> [1, 1, 2] - [1]
=> [2]
> [1, 1, 2].difference [1]
=> [2]
23 24 25 |
# File 'lib/core/facets/array/remove.rb', line 23 def remove(other_ary) dup.remove!(other_ary) end |
#remove!(other_ary) ⇒ Object
For each element of other_ary, deletes the first element from self that is equal to that element (using delete_at, not delete).
This is the in-place version of remove.
32 33 34 35 36 37 38 |
# File 'lib/core/facets/array/remove.rb', line 32 def remove!(other_ary) other_ary.each do |el| i = index(el) delete_at(i) if i end self 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.
TODO: This is based on Haskell’s span, but the name is not intuitive for Ruby. Consider a more descriptive name (e.g. split_while). Also consider adding the inverse (Haskell’s break), which splits where the predicate first becomes true.
22 23 24 25 26 27 28 |
# File 'lib/core/facets/array/span.rb', line 22 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
22 23 24 25 |
# File 'lib/core/facets/array/standard_deviation.rb', line 22 def standard_deviation warn "Array#standard_deviation is deprecated. Use Array#stddev or Array#sd instead.", uplevel: 1 stddev end |
#stddev ⇒ 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 stddev return nil if empty? Math.sqrt(variance) end |
#step(n, offset = 0) ⇒ Object
Iterate over every nth element of an array.
An optional offset can be given to start from a specific index (default is 0).
[:a, :b, :c, :d, :e, :f].step(2).to_a #=> [:a, :c, :e]
[:a, :b, :c, :d, :e, :f].step(2, 1).to_a #=> [:b, :d, :f]
[:a, :b, :c, :d, :e, :f].step(3).to_a #=> [:a, :d]
r = []
[:a, :b, :c, :d].step(2) { |x| r << x }
r #=> [:a, :c]
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, offset=0) #:yield: if block_given? (offset...size).step(n).each do |i| yield(fetch(i)) end else Enumerator.new do |y| (offset...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_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_ranges ⇒ Object Also known as: arrange, rangify
Produces an array of ranges from the values in the array. Contiguous values and overlapping ranges are merged. Single values are returned as single-element ranges (e.g. 1..1).
Examples
[1,2,3,6,7,8].to_ranges #=> [1..3, 6..8]
[3,4,5,1,6,9,8].to_ranges #=> [1..1, 3..6, 8..9]
[10..15, 16..20, 21, 22].to_ranges #=> [10..22]
Assumes inclusive ranges (i.e. 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, Ryan Duryea
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/core/facets/array/to_ranges.rb', line 22 def to_ranges array = compact.uniq.sort_by { |e| Range === e ? e.first : e } result = 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 # Ensure all elements are ranges result.map { |e| Range === e ? e : e..e } 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!(&block) ⇒ 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!(&block) #:yield: warn "Array#uniq_by! is deprecated. Use Array#uniq!(&block) instead.", uplevel: 1 uniq!(&block) 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 |