# Module: Cartesian

Defined in:
lib/cartesian.rb,
lib/cartesian/version.rb

:nodoc:

## Constant Summary

VERSION =

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

`"0.6.4"`

## Class Method Summary (collapse)

• Behaves as product, except for the elements are joined.

• Produces the cartesian product of self and other.

## Instance Method Summary (collapse)

• - (Object) **(fixnum) (also: #power!)

Concise way of iterating multi-dimensionally over the same array or range.

• Cartesian.joined_product for mixin.

• - (Object) x(other) (also: #cartesian, #right_product)

Convenient way of iterating over the elements.

## Class Method Details

### + (Object) joined_product(first, second)

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"]``
 ``` 65 66 67``` ```# File 'lib/cartesian.rb', line 65 def Cartesian.joined_product(first, second) product(first, second).map {|pair| pair.join } end```

### + (Object) product(first, second)

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"]]``
 ``` 53 54 55``` ```# File 'lib/cartesian.rb', line 53 def Cartesian.product(first, second) first.x(second).to_a end```

## Instance Method Details

### - (Object) **(fixnum) Also known as: power!

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.

 ``` 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157``` ```# File 'lib/cartesian.rb', line 143 def **(fixnum) if fixnum < 0 raise ArgumentError, "negative power" elsif fixnum == 0 return [] elsif fixnum == 1 return self else iter = CartesianIterator.new(self, self) (fixnum-2).times do iter.product!(self) end iter end end```

### - (Object) joined_cartesian(other)

Cartesian.joined_product for mixin.

 ``` 71 72 73``` ```# File 'lib/cartesian.rb', line 71 def joined_cartesian(other) Cartesian.joined_product(self, other) end```

### - (Object) left_product(other)

 ``` 112 113 114 115 116 117 118 119``` ```# File 'lib/cartesian.rb', line 112 def left_product(other) case other when CartesianIterator other.right_product(self) else CartesianIterator.new(other, self) end end```

### - (Object) x(other) Also known as: cartesian, right_product

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.

 ``` 101 102 103 104 105 106 107 108``` ```# File 'lib/cartesian.rb', line 101 def x(other) case other when CartesianIterator other.left_product(self) else CartesianIterator.new(self, other) end end```