Ruby/Array/Array Extension
Материал из Wiki.crossplatform.ru
Add a new method to Array class
class Array def each_from_both_sides front_index = 0 back_index = self.length-1 while front_index <= back_index yield self[front_index] front_index += 1 if front_index <= back_index yield self[back_index] back_index -= 1 end end end end new_array = [] [1,2,3,4,5].each_from_both_sides { |x| new_array << x } p new_array # => [1, 5, 2, 4, 3]
Add method to Array class to convert an array to a hash
class Array def into_hash(h) unless size % 2 == 0 raise StandardError, "Expected array with even number of elements" end 0.step(size-1, 2) { |x| h[self[x]] = self[x+1] } h end end squares = [1,1,2,3,4,9] results = {} p squares.into_hash(results) # => {1=>1, 2=>3, 4=>9} [1,1,2].into_hash(results) # StandardError: Expected array with even number of elements
Add new operator for Array
class Array def ^(other) (self | other) - (self & other) end end x = [1, 2, 3, 4, 5] y = [3, 4, 5, 6, 7] z = x ^ y # [1, 2, 6, 7]
Add shuffle method to Array class
class Array def shuffle! each_index do |i| j = rand(length-i) + i self[j], self[i] = self[i], self[j] end end def shuffle dup.shuffle! end end
Add subset and superset operator for Array
class Array def subset?(other) self.each do |x| if !(other.include? x) return false end end true end def superset?(other) other.subset?(self) end end a = [1, 2, 3, 4] b = [2, 3] c = [2, 3, 4, 5] flag1 = c.subset? a # false flag2 = b.subset? a # true flag3 = c.superset? b # true
Add your method to system data type
#!/usr/bin/env ruby class Array def array_of_ten (1..10).to_a end end arr = Array.new ten = arr.array_of_ten p ten # => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Array cartesian
module Enumerable def cartesian(other) res = [] each { |x| other.each { |y| res << [x, y] } } return res end end p [1,2,3].cartesian(["a",5,6]) # => [[1, "a"], [1, 5], [1, 6], # => [2, "a"], [2, 5], [2, 6], # => [3, "a"], [3, 5], [3, 6]]
convert array to a hash
class Array def invert h={} self.each_with_index{|x,i| h[x]=i} h end end a = ["red","yellow","orange"] h = a.invert # {"orange"=>2, "yellow"=>1, "red"=>0}
each from both sides
class Array def each_from_both_sides() front_index = 0 back_index = self.length-1 while front_index <= back_index yield self[front_index] front_index += 1 if front_index <= back_index yield self[back_index] back_index -= 1 end end end end %w{1,2,3,4,5}.each_from_both_sides { |x| puts x }
Extends array comparsion method
class Array def <(other) (self <=> other) == -1 end def <=(other) (self < other) or (self == other) end def >(other) (self <=> other) == 1 end def >=(other) (self > other) or (self == other) end end
Extract array in place
class Array def extract! ary = self.dup self.reject! { |x| yield x } ary - self end end p a = ("a".."h").to_a p a.extract! { |x| x < "e" && x != "b" } # => ["a", "c", "d"] p a # => ["b", "e", "f", "g", "h"]
Override array method
class Array2 < Array def [](index) if index>0 super(index-1) else raise IndexError end end def []=(index,obj) if index>0 super(index-1,obj) else raise IndexError end end end x = Array2.new x[1]=5 x[2]=3 x[0]=1 # Error x[-1]=1 # Error
Resequence the array
class Array def randomize arr=self.dup arr.collect { arr.slice!(rand arr.length) } end def randomize! arr=self.dup result = arr.collect { arr.slice!(rand arr.length) } self.replace result end end x = [1, 2, 3, 4, 5] y = x.randomize # [3, 2, 4, 1 ,5] x.randomize! # x is now [3, 5, 4, 1, 2] class Array def pick_random self[rand(self.length)] end end
Set permutation for Array
class Array def powerset num = 2**size ps = Array.new(num, []) self.each_index do |i| a = 2**i b = 2**(i+1) - 1 j = 0 while j < num-1 for j in j+a..j+b ps[j] += [self[i]] end j += 1 end end ps end end x = [1, 2, 3] y = x.powerset # y is now: # [[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3]]
strip values from array
class Array def strip_values_at!(*args) args.each do |x| #For each mentioned index, replace its value with a dummy object. values = [] dummy = Object.new args.each do |i| if i < size values << self[i] self[i] = dummy end end #Strip out the dummy object. delete(dummy) return values end end end p a = ("a".."h").to_a p a.strip_values_at!(1, 0, -2) # => ["b", "a", "g"] p a # => ["c", "d", "e", "f", "h"] p a.strip_values_at!(1000) # => [] p a # => ["c", "d", "e", "f", "h"]
Use hash to count elements in an array
class Array def count k=Hash.new(0) self.each{|x| k[x]+=1 } k end end meal = %w[spam spam eggs ham eggs spam] items = meal.count # items is {"ham" => 1, "spam" => 3, "eggs" => 2} spams = items["spam"] # 3