lib/cartesian.rb in Cartesian-0.1.0 vs lib/cartesian.rb in Cartesian-0.2.1
- old
+ new
@@ -28,20 +28,22 @@
# require 'cartesian'
# foo = [1, 2]
# bar = ["a", "b"]
# foo.cartesian(bar) #=> [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]
+require 'cartesian_iterator'
+
module Cartesian
# Produces the cartesian product of self and other.
# The result is an array of pairs (i.e. two-element arrays).
#
- # cartesian( [1,2], %w(A B) ) #=> [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]
+ # Cartesian::product( [1,2], %w(A B) ) #=> [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]
#
# or, if mixed in into Array,
#
- # [1,2].cartesian %w(A B) #=> [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]
+ # [1,2].cartesian %w(A B) #=> [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]
#
def Cartesian.product(first, second)
result = []
first.each do |a|
second.each do |b|
@@ -57,25 +59,59 @@
Cartesian.product(self, other)
end
# Behaves as product, except for the elements are joined.
#
- # joined_cartesian( [1,2], %w(A B) ) #=> ["1A", "1B", "2A", "2B"]
+ # Cartesian::joined_cartesian( [1,2], %w(A B) ) #=> ["1A", "1B", "2A", "2B"]
#
# or, if mixed in into Array,
#
- # [1,2].joined_cartesian %w(A B) #=> ["1A", "1B", "2A", "2B"]
+ # [1,2].joined_cartesian %w(A B) #=> ["1A", "1B", "2A", "2B"]
#
def Cartesian.joined_product(first, second)
product(first, second).map {|pair| pair.join }
end
# Cartesian.joined_product for mixin.
#
def joined_cartesian(other)
Cartesian.joined_product(self, other)
end
+
+ # Convenient way of iterating over the elements.
+ # Preferable when the cartesian product array
+ # is not needed, for the consumption of memory
+ # is fixed and very small, in contrast with the
+ # exponential memory requirements of the
+ # conventional approach.
+ #
+ # for row, col in (1..10).x(1..30)
+ # Matrix[row, col] = row**2 + col**3
+ # end
+ #
+ # Of course, calls can be chained as in
+ #
+ # for x, y, z in (1..10).x(1..10).x(1..10)
+ # # ... do something ...
+ # end
+ #
+ #--
+ # 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)
+ end
end
class Array
+ include Cartesian
+end
+
+class Range
include Cartesian
end