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

- old
+ new

@@ -27,10 +27,11 @@ # as mixin # require 'cartesian' # foo = [1, 2] # bar = ["a", "b"] # foo.cartesian(bar) #=> [[1, "a"], [1, "b"], [2, "a"], [2, "b"]] +# require 'cartesian_iterator' module Cartesian @@ -41,34 +42,14 @@ # # or, if mixed in into Array, # # [1,2].cartesian %w(A B) #=> [[1, "A"], [1, "B"], [2, "A"], [2, "B"]] # - # optional parameter {:flatten => true} - # - def Cartesian.product(first, second, params={}) - params[:flatten] ||= true - - result = [] - first.each do |a| - second.each do |b| - if params[:flatten] == true - result << [a, b].flatten - else - result << [a, b] - end - end - end - result + def Cartesian.product(first, second) + first.x(second).to_a end - # Cartesian.product for mixin. - # - def cartesian(other, params={}) - Cartesian.product(self, other, params) - end - # Behaves as product, except for the elements are joined. # # Cartesian::joined_cartesian( [1,2], %w(A B) ) #=> ["1A", "1B", "2A", "2B"] # # or, if mixed in into Array, @@ -104,18 +85,34 @@ # #-- # for letter, number in %w{a b c}.x(1..3) # ... do something ... # end - # #++ + # # Beware that both +self+ and +other+ must implement # +to_a+, i.e., be convertible to array. # def x(other) - CartesianIterator.new(self, other) + case other + when CartesianIterator + other.left_product(self) + else + CartesianIterator.new(self, other) + end end + alias cartesian x + alias right_product x + + def left_product(other) + case other + when CartesianIterator + other.right_product(self) + else + CartesianIterator.new(other, self) + end + end # Concise way of iterating multi-dimensionally # over the same array or range. # # For instance, @@ -137,18 +134,18 @@ # # It also works with Range objects. # def **(fixnum) if fixnum < 0 - raise ArgumentError, "power must be non-negative" + raise ArgumentError, "negative power" elsif fixnum == 0 return [] elsif fixnum == 1 return self else iter = CartesianIterator.new(self, self) (fixnum-2).times do - iter.x(self) + iter.product!(self) end iter end end alias :power! :**