Posted By

ishikawa on 02/16/08


Tagged

array ruby


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

webstic


Array#product for Ruby 1.8


 / 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.

  1. class Array
  2.  
  3. # Array#product
  4. # -------------
  5. # Returns the cartesian product of the receiver and the arrays given as arguments.
  6. #
  7. # Usage:
  8. # [1, 2, 3].product([4, 5]) # => [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]
  9. # [1, 2].product([1, 2]) # => [[1, 1], [1, 2], [2, 1], [2, 2]]
  10. # [1, 2].product([3, 4],[5, 6]) # => [[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6],
  11. # # [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]
  12. # [1, 2].product() # => [[1], [2]]
  13. # [1, 2].product([]) # => []
  14. #
  15. # [1] * [2, 3] # => [[1, 2], [1, 3]]
  16. # [1, 2] * [3, 4] # => [[1, 3], [1, 4], [2, 3], [2, 4]]
  17. #
  18. def product(*others)
  19. arrays = [ self.map {|i| [i] } ].concat(others)
  20. arrays.inject do |result, item|
  21. (result * item).map do |t|
  22. t[0].dup << t[1]
  23. end
  24. end
  25. end
  26.  
  27. def multiplication_operator_with_product(other)
  28. unless other.kind_of? Array
  29. multiplication_operator_without_product(other)
  30. else
  31. self.inject([]) do |ret, i|
  32. ret.concat( other.map {|j| [i, j]} )
  33. end
  34. end
  35. end
  36.  
  37. alias_method :multiplication_operator_without_product, :*
  38. alias_method :*, :multiplication_operator_with_product
  39.  
  40. end

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: adrianomitre on July 26, 2009

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/

You need to login to post a comment.