class Array
Public Instance Methods
Format–Uses the first string in array for which the corresponding combination of other_array does not contain blank elements as a format specification, and returns the result of applying it to that combination (cf. String#%). Returns an empty string if other_array is empty.
Applies to string argument accordingly: First string in array applied to str; empty string if str is empty.
# File lib/nuggets/array/format.rb 42 def %(args) 43 opts = { sep: ', ' } 44 opts.update(pop) if last.is_a?(::Hash) 45 46 default = lambda { |n| ['%s'] * n * opts[:sep] } 47 48 case args 49 when ::String 50 return (first || default[1]) % args unless 51 args.nil? || args.empty? 52 when ::Array 53 i = 0 54 [*args].comb { |x| 55 return (self[i] || default[x.size]) % x unless 56 x.empty? || x.any? { |y| y.nil? || y.empty? } 57 58 i += 1 59 } 60 end 61 62 '' 63 end
Check whether array is (strictly) ascending.
# File lib/nuggets/array/monotone.rb 51 def ascending?(strict = false) 52 monotone?(strict ? :< : :<=) 53 end
Returns an array of arrays of each possible n
-combination of array for each given n
. If a block is given, each combination
is yielded to it. Based on <blade.nagaokaut.ac.jp/~sinara/ruby/math/combinatorics/array-comb.rb>.
# File lib/nuggets/array/combination.rb 36 def comb(*sizes) 37 # If no sizes are given, produce all! 38 sizes = (0..size).to_a.reverse if sizes.empty? 39 40 combinations, collect_and_yield = [], lambda { |combination| 41 yield combination if block_given? 42 combinations << combination 43 } 44 45 sizes.each { |n| 46 case n 47 when 0 # Short-cut (breaks recursion) 48 collect_and_yield[[]] 49 when 1..size # Ignore out-of-range values 50 self[1..-1].comb(n - 1) { |combination| 51 collect_and_yield[combination.unshift(first)] 52 } 53 self[1..-1].comb(n) { |combination| 54 collect_and_yield[combination] 55 } 56 end 57 } 58 59 combinations 60 end
Check whether array is (strictly) descending.
# File lib/nuggets/array/monotone.rb 69 def descending?(strict = false) 70 monotone?(strict ? :> : :>=) 71 end
Flatten array by one level only. Pretty straight-forward port of David Alan Black's flattenx C implementation (though much slower, of course ;-).
# File lib/nuggets/array/flatten_once.rb 34 def flatten_once 35 flat = [] 36 37 each { |element| 38 if element.is_a?(::Array) 39 flat += element 40 else 41 flat << element 42 end 43 } 44 45 flat 46 end
Destructive version of flatten_once
.
# File lib/nuggets/array/flatten_once.rb 52 def flatten_once! 53 replace(flatten_once) 54 end
Force order, but ignore non-existing and keep remaining.
Examples:
[:created_at, :email, :login, :updated_at].in_order(:login, :email) #=> [:login, :email, :created_at, :updated_at] [:created_at, :email, :login, :updated_at].in_order(:email, :address) #=> [:email, :created_at, :login, :updated_at]
# File lib/nuggets/array/in_order.rb 37 def in_order(*ordered) 38 ordered &= self 39 ordered + (self - ordered) 40 end
Destructive version of in_order
.
# File lib/nuggets/array/in_order.rb 46 def in_order!(*ordered) 47 replace(in_order(*ordered)) 48 end
Check whether array is monotone according to operator
.
# File lib/nuggets/array/monotone.rb 33 def monotone?(operator = nil) 34 if [nil, true, false].include?(operator) 35 ascending?(operator) || descending?(operator) 36 else 37 inject { |a, b| 38 return false unless a.send(operator, b) 39 b 40 } 41 42 true 43 end 44 end
Returns the only element of array. Raises an IndexError if array's size is not 1, unless parameter true
is passed.
Idea stolen from Gavin Sinclair's Ruby Extensions Project.
# File lib/nuggets/array/only.rb 37 def only(relax = size == 1) 38 relax ? first : raise(::IndexError, 'not a single-element array') 39 end
Randomly pick an item from array.
# File lib/nuggets/array/rand.rb 33 def rand 34 at(::Kernel.rand(size)) 35 end
Shuffles array in random order. Select a different shuffling algorithm: Array.send(:alias_method, :shuffle, :shuffle_kfy)
.
# File lib/nuggets/array/shuffle.rb 34 def shuffle 35 sort_by { ::Kernel.rand } 36 end
Destructive version of shuffle
.
# File lib/nuggets/array/shuffle.rb 58 def shuffle! 59 replace shuffle 60 end
Non-destructive version of shuffle_kfy!
.
# File lib/nuggets/array/shuffle.rb 50 def shuffle_kfy 51 dup.shuffle_kfy! 52 end
Shuffles array in random order using the Knuth-Fisher-Yates algorithm.
# File lib/nuggets/array/shuffle.rb 79 def shuffle_kfy! 80 (length - 1).downto(0) { |i| 81 n = rand(i + 1) 82 self[n], self[i] = self[i], self[n] 83 } 84 85 self 86 end
Non-destructive version of shuffle_knuth!
.
# File lib/nuggets/array/shuffle.rb 42 def shuffle_knuth 43 dup.shuffle_knuth! 44 end
Shuffles array in random order using Knuth's algorithm.
# File lib/nuggets/array/shuffle.rb 66 def shuffle_knuth! 67 0.upto(length - 2) { |i| 68 n = i + rand(length - i) 69 self[i], self[n] = self[n], self[i] 70 } 71 72 self 73 end
# File lib/nuggets/dotted_decimal.rb 55 def sort_by_dotted_decimal 56 sort_by { |i| i.split('.').map { |j| j.to_i } } 57 end
Check whether array is strictly ascending.
# File lib/nuggets/array/monotone.rb 60 def strictly_ascending? 61 ascending?(true) 62 end
Check whether array is strictly descending.
# File lib/nuggets/array/monotone.rb 78 def strictly_descending? 79 descending?(true) 80 end
If neither value
nor block is given, converts array, taken as an array of key/value pairs, into a hash, preserving sub-arrays (Thus: hash.to_a.to_h == hash
). Otherwise, maps each element of array to value
or the result of the block.
Examples:
[[0, 0], [1, [2, 3]]].to_h #=> { 0 => 0, 1 => [2, 3] } %w[a b c d].to_h #=> { "a" => "b", "c" => "d" } %w[a b c d].to_h(1) #=> { "a" => 1, "b" => 1, "c" => 1, "d" => 1 } %w[a b].to_h { |e| e * 2 } #=> { "a" => "aa", "b" => "bb" }
# File lib/nuggets/array/to_hash.rb 46 def to_hash(value = default = true) 47 hash = {} 48 49 if block_given? 50 raise ::ArgumentError, 'both block and value argument given' unless default 51 52 each { |element| hash[element] = yield element } 53 elsif !default 54 each { |element| hash[element] = value } 55 else 56 return ::Hash[*flatten_once] 57 end 58 59 hash 60 end