The Cartesian module provide methods for the calculation of the cartesian producted between two enumerable objects.
It can also be easily mixed in into any enumerable class, i.e. any class with Enumerable module mixed in. Notice that the names of the methods for mixin are different.
Module:
Cartesian::product(foo, bar)
Mixin:
foo.cartesian( bar )
The module is automatically mixed in Array class.
Adriano MITRE
as module
require 'cartesian' foo = [1, 2] bar = ["a", "b"] Cartesian::product(foo, bar) #=> [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]
as mixin
require 'cartesian' foo = [1, 2] bar = ["a", "b"] foo.cartesian(bar) #=> [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]
Unfortunately, as of now, the version data must be replicated in ../cartesian.rb, due to a mix of newgem versions, each requiring a different one. Not DRY :P
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,
[1,2].joined_cartesian %w(A B) #=> ["1A", "1B", "2A", "2B"]
# File lib/cartesian.rb, line 65 65: def Cartesian.joined_product(first, second) 66: product(first, second).map {|pair| pair.join } 67: end
Produces the cartesian product of self and other. The result is an array of pairs (i.e. two-element arrays).
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"]]
# File lib/cartesian.rb, line 53 53: def Cartesian.product(first, second) 54: first.x(second).to_a 55: 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.
# File lib/cartesian.rb, line 143 143: def **(fixnum) 144: if fixnum < 0 145: raise ArgumentError, "negative power" 146: elsif fixnum == 0 147: return [] 148: elsif fixnum == 1 149: return self 150: else 151: iter = CartesianIterator.new(self, self) 152: (fixnum-2).times do 153: iter.product!(self) 154: end 155: iter 156: end 157: end
Cartesian.joined_product for mixin.
# File lib/cartesian.rb, line 71 71: def joined_cartesian(other) 72: Cartesian.joined_product(self, other) 73: end
# File lib/cartesian.rb, line 112 112: def left_product(other) 113: case other 114: when CartesianIterator 115: other.right_product(self) 116: else 117: CartesianIterator.new(other, self) 118: end 119: 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
Beware that both self and other must implement to_a, i.e., be convertible to array.
# File lib/cartesian.rb, line 101 101: def x(other) 102: case other 103: when CartesianIterator 104: other.left_product(self) 105: else 106: CartesianIterator.new(self, other) 107: end 108: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.