/ Published in: Ruby
URL: http://weblog.metareal.org/2008/02/16/array-product-for-ruby-1-8/
Returns the cartesian product of the receiver and the arrays given as arguments.
Expand |
Embed | Plain Text
class Array # Array#product # ------------- # Returns the cartesian product of the receiver and the arrays given as arguments. # # Usage: # [1, 2, 3].product([4, 5]) # => [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]] # [1, 2].product([1, 2]) # => [[1, 1], [1, 2], [2, 1], [2, 2]] # [1, 2].product([3, 4],[5, 6]) # => [[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], # # [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]] # [1, 2].product() # => [[1], [2]] # [1, 2].product([]) # => [] # # [1] * [2, 3] # => [[1, 2], [1, 3]] # [1, 2] * [3, 4] # => [[1, 3], [1, 4], [2, 3], [2, 4]] # def product(*others) arrays = [ self.map {|i| [i] } ].concat(others) arrays.inject do |result, item| (result * item).map do |t| t[0].dup << t[1] end end end def multiplication_operator_with_product(other) unless other.kind_of? Array multiplication_operator_without_product(other) else self.inject([]) do |ret, i| ret.concat( other.map {|j| [i, j]} ) end end end alias_method :multiplication_operator_without_product, :* alias_method :*, :multiplication_operator_with_product end
Comments
Subscribe to comments
You need to login to post a comment.

Unfortunately, this method uses too much memory, storing the whole cartesian product Array in memory even its elements are needed only one at a time. One nicer alternative is the Cartesian module:
"The Cartesian module provide methods for the calculation of the cartesian producted between two enumberable objects. It can also be easily mixed in into any enumberable class, i.e. any class with Enumerable module mixed in."
The Cartesian module is available at http://rubyforge.org/projects/cartesian/