lib/cartesian.rb in Cartesian-0.2.1 vs lib/cartesian.rb in Cartesian-0.2.3

- old
+ new

@@ -41,24 +41,32 @@ # # or, if mixed in into Array, # # [1,2].cartesian %w(A B) #=> [[1, "A"], [1, "B"], [2, "A"], [2, "B"]] # - def Cartesian.product(first, second) + # optional parameter {:flatten => true} + # + def Cartesian.product(first, second, params={}) + params[:flatten] ||= true + result = [] first.each do |a| second.each do |b| - result << [a, b] + if params[:flatten] == true + result << [a, b].flatten + else + result << [a, b] + end end end result end # Cartesian.product for mixin. # - def cartesian(other) - Cartesian.product(self, other) + 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"] @@ -104,9 +112,41 @@ # +to_a+, i.e., be convertible to array. # def x(other) CartesianIterator.new(self, other) end + + # Concise way of iterating multi-dimensionally + # over the same array or range. + # + # For instance, + # + # for x,y,z in [0,1]**3 + # puts [x, y, z].join(',') + # end + # + # produces the following output + # + # 0,0,0 + # 0,0,1 + # 0,1,0 + # 0,1,1 + # 1,0,0 + # 1,0,1 + # 1,1,0 + # 1,1,1 + # + # It also works with Range objects. + # + def **(fixnum) + return self if fixnum <= 1 + iter = CartesianIterator.new(self, self) + (fixnum-2).times do + iter.x(self) + end + iter + end + alias :power! :** end class Array include Cartesian end