lib/cartesian_iterator.rb in Cartesian-0.3.0 vs lib/cartesian_iterator.rb in Cartesian-0.4.1

- old
+ new

@@ -1,76 +1,109 @@ require 'grid_search' class CartesianIterator include GridSearch - - def initialize(foo, bar) - @lists = [] - @tot_iter = 1 - x(foo) - x(bar) - end - - def x(other) - @lists << other.to_a.dup - @tot_iter *= @lists[-1].size - self - end - - def each - return false if @tot_iter < 1 - - elems = [] - for list in @lists - elems << list.restart_and_raw_next - end - yield *elems - - last_list_index = @lists.size-1 - n = last_list_index - loop do - if elems[n] = @lists[n].raw_next - yield *elems - n = last_list_index - next - elsif n > 0 - elems[n] = @lists[n].restart_and_raw_next - n -= 1 - else - return true - end - end - end - - def to_a - array = [] - self.each {|*element| array << element } - array + + def initialize(foo, bar) + @lists = [] + @tot_iter = 1 + product!(foo) + product!(bar) end + + def dup + Marshal.load(Marshal.dump(self)) + end + + def equal(other) + self.instance_variables.each do |var_name| + return false if self.instance_variable_get(var_name) != other.instance_variable_get(var_name) + end + true + end + alias == equal -end - -module Iterable - def start - @next_index = -1 - true - end - alias :restart :start - - def next - @next_index or restart - raw_next - end - - def raw_next - self[@next_index += 1] - end - - def restart_and_raw_next - self[@next_index = 0] - end -end - -class Array - include Iterable -end + def product!(other) + @lists << other.to_a.dup + @tot_iter *= @lists[-1].size + self + end + alias right_product! product! + alias x! product! + + def left_product!(other) + @lists.unshift other.to_a.dup + @tot_iter *= @lists[-1].size + self + end + + def product(other) + (result = self.dup).product!(other) + result + end + alias right_product product + alias x product + + def left_product(other) + (result = self.dup).left_product!(other) + result + end + + def each + return false if @tot_iter < 1 + + elems = [] + for list in @lists + elems << list.restart_and_raw_next + end + yield *elems + + last_list_index = @lists.size-1 + n = last_list_index + loop do + if elems[n] = @lists[n].raw_next + yield *elems + n = last_list_index + next + elsif n > 0 + elems[n] = @lists[n].restart_and_raw_next + n -= 1 + else + return true + end + end + end + + def to_a + array = [] + self.each {|*element| array << element } + array + end + alias to_ary to_a + +end + +module Iterable + def restart + @next_index = -1 + true + end + alias start restart + + def next + @next_index or restart + raw_next + end + + def raw_next + self[@next_index += 1] + end + + def restart_and_raw_next + self[@next_index = 0] + end +end + +class Array + include Iterable +end