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! :**