class Array
Public Class Methods
Create a 2D matrix out of arrays
# File lib/epitools/core_ext/array.rb, line 196 def self.matrix(height, width, initial_value=nil) if block_given? height.times.map do |row| width.times.map do |col| yield(row, col) end end else height.times.map do [initial_value] * width end end end
Public Instance Methods
Overridden multiplication operator. Now lets you multiply the Array
by another Array
or Enumerable
.
Array
* Integer
== a new array with <Integer> copies of itself inside Array
* String
== a new string containing the elements, joined by the <String> Array
* {Array or Enumerable} == the cross product (aka. cartesian product) of both arrays
# File lib/epitools/core_ext/array.rb, line 311 def *(other) case other when Integer, String old_multiply(other) when Enumerable cross_product(other).to_a end end
Multiply the array by itself `n` times.
# File lib/epitools/core_ext/array.rb, line 323 def **(n) super.to_a end
Divide the array into n pieces.
# File lib/epitools/core_ext/array.rb, line 133 def / pieces piece_size = (size.to_f / pieces).ceil each_slice(piece_size).to_a end
XOR operator
# File lib/epitools/core_ext/array.rb, line 96 def ^(other) (self | other) - (self & other) end
# File lib/epitools/permutations.rb, line 37 def all_pairs(reflexive=false) (0...size).each do |a| start = reflexive ? a : a+1 (start...size).each do |b| yield self[a], self[b] end end end
Return column n of a 2D array
# File lib/epitools/core_ext/array.rb, line 188 def column(n) columns[n]&.rtrim! end
# File lib/epitools/core_ext/array.rb, line 171 def columns cols = transpose_with_padding cols.each &:rtrim! cols end
Takes an array of numbers, puts them into equal-sized buckets, and counts the buckets (aka. A Histogram!)
Examples:
[1,2,3,4,5,6,7,8,9].histogram(3) #=> [3,3,3] [1,2,3,4,5,6,7,8,9].histogram(2) #=> [4,5] [1,2,3,4,5,6,7,8,9].histogram(2, ranges: true) #=> { 1.0...5.0 => 4, 5.0...9.0 => 5 }
# File lib/epitools/core_ext/array.rb, line 269 def histogram(n_buckets=10, options={}) use_ranges = options[:ranges] || options[:hash] min_val = min max_val = max range = (max_val - min_val) bucket_size = range.to_f / n_buckets buckets = [0]*n_buckets # p [range, bucket_size, buckets, min_val, max_val] each do |e| bucket = (e - min_val) / bucket_size bucket = n_buckets - 1 if bucket >= n_buckets # p [:e, e, :bucket, bucket] buckets[bucket] += 1 end if use_ranges ranges = (0...n_buckets).map do |n| offset = n*bucket_size (min_val + offset) ... (min_val + offset + bucket_size) end Hash[ ranges.zip(buckets) ] else buckets end end
Find the statistical mean
# File lib/epitools/core_ext/array.rb, line 73 def mean sum / size.to_f end
Find the statistical median (middle value in the sorted dataset)
# File lib/epitools/core_ext/array.rb, line 81 def median sort.middle end
Pick the middle element
# File lib/epitools/core_ext/array.rb, line 66 def middle self[(size-1) / 2] end
Find the statistical “mode” (most frequently occurring value)
# File lib/epitools/core_ext/array.rb, line 89 def mode counts.max_by { |k,v| v }.first end
Removes the elements from the array for which the block evaluates to true. In addition, return the removed elements.
For example, if you wanted to split an array into evens and odds:
nums = [1,2,3,4,5,6,7,8,9,10,11,12] even = nums.remove_if { |n| n.even? } # remove all even numbers from the "nums" array and return them odd = nums # "nums" now only contains odd numbers
# File lib/epitools/core_ext/array.rb, line 32 def remove_if(&block) removed = [] delete_if do |x| if yield(x) removed << x true else false end end removed end
Return row n of a 2D array
# File lib/epitools/core_ext/array.rb, line 181 def row(n) rows[n] end
Pseudo-matrix methods
# File lib/epitools/core_ext/array.rb, line 167 def rows self end
Return a copy of this array which has been extended to target_width by adding nils to the end (right side)
# File lib/epitools/core_ext/array.rb, line 229 def rpad(target_width) dup.rpad!(target_width) end
Extend the array the target_width by adding nils to the end (right side)
# File lib/epitools/core_ext/array.rb, line 219 def rpad!(target_width) if target_width > size and target_width > 0 self[target_width-1] = nil end self end
Like `rtrim!`, but returns a trimmed copy of the array
# File lib/epitools/core_ext/array.rb, line 159 def rtrim(element=nil) dup.rtrim!(element) end
Remove instances of “element” from the end of the array (using `Array#pop`)
# File lib/epitools/core_ext/array.rb, line 151 def rtrim!(element=nil) pop while last == element self end
see: Enumerable#rzip
# File lib/epitools/core_ext/array.rb, line 50 def rzip(other) super.to_a # reverse_each.zip(other.reverse_each).reverse_each.to_a # reverse.zip(other.reverse).reverse # That's a lotta reverses! end
# File lib/epitools/core_ext/array.rb, line 113 def sample(n=1) return self[rand sz] if n == 1 sz = size indices = [] loop do indices += (0..n*1.2).map { rand sz } indices.uniq break if indices.size >= n end values_at(*indices[0...n]) end
# File lib/epitools/core_ext/array.rb, line 104 def shuffle sort_by { rand } end
See: Enumerable#split_at
# File lib/epitools/core_ext/array.rb, line 59 def split_at(*args, &block) super.to_a end
flatten.compact.uniq
# File lib/epitools/core_ext/array.rb, line 14 def squash flatten.compact.uniq end
# File lib/epitools/core_ext/array.rb, line 237 def to_h if self.first.is_a? Array Hash[self] else Hash[*self] end end
Transpose an array that could have rows of uneven length
# File lib/epitools/core_ext/array.rb, line 143 def transpose_with_padding max_width = map(&:size).max map { |row| row.rpad(max_width) }.transpose end