Noob: The ruby way to multiple Array by multiple?

I want to make a Array multipled by another Array, and the following semantic.
For example:
[1, 2, 3] * [4, 5]
then I will want [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]] returned.

I have the following code snippet to implement this function:

class Array
  alias_method :orig_multiple, :*
  def *(arg)
    case arg
    when Array
      if arg.empty?
        self
      else
        inject([]) do |product, item|
          product.concat(arg.collect do |i|
                           case item
                           when Array
                             item.clone << i
                           else
                             [item, i]
                           end
                         end)
        end
      end
    else
      orig_multiple(arg)
    end
  end
end

It works but seems ugly.

Could anyone please to give me a clue to make it beauty and rubish!

Thx in advance.
Eric

Eric Luo wrote:

I want to make a Array multipled by another Array, and the following semantic.
For example:
[1, 2, 3] * [4, 5]
then I will want [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]] returned.

I have the following code snippet to implement this function:

class Array
  alias_method :orig_multiple, :*
  def *(arg)
    case arg
    when Array
      if arg.empty?
        self
      else
        inject() do |product, item|
          product.concat(arg.collect do |i|
                           case item
                           when Array
                             item.clone << i
                           else
                             [item, i]
                           end
                         end)
        end
      end
    else orig_multiple(arg)
    end
  end
end

It works but seems ugly.

Could anyone please to give me a clue to make it beauty and rubish!

Thx in advance.
Eric

res =
a1.each {|e1| a2.each {|e2| res << [e1,e2]}}

Or, if you prefer inject

a1.inject() {|arr,e1| a2.each {|e2| arr << [e1,e2]}; arr }

Kind regards

  robert

a = [1, 2, 3]
b = [4, 5]

(a * b.size).zip(b * a.size).sort
# => [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]

# or w/o sort:
a.zip(a).flatten.zip(b * a.size)
# => [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]

# the latter only works as-is because b.size == 2 (a.zip(a).flatten ~= a * 2).
# If b.size were 3, you'd add b.size-1 a's to the first zip arg list:

b << 6
a.zip(a, a).flatten.zip(b * a.size)
# => [[1, 4], [1, 5], [1, 6], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6]]

# if order doesn't actually matter, the first solution is the cleanest:

class Array
   def x(b)
     a = self
     (a * b.size).zip(b * a.size)
   end
end

a.x b
=> [[1, 4], [2, 5], [3, 6], [1, 4], [2, 5], [3, 6], [1, 4], [2, 5], [3, 6]]

···

On Mar 28, 2006, at 2:08 AM, Eric Luo wrote:

I want to make a Array multipled by another Array, and the following semantic.
For example:
[1, 2, 3] * [4, 5]
then I will want [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]] returned.

--
ryand-ruby@zenspider.com
Seattle.rb | Home - Seattle.rb
http://blog.zenspider.com/

Ryan Davis schrieb:

a = [1, 2, 3]
b = [4, 5]

(a * b.size).zip(b * a.size).sort
# => [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]

...

class Array
  def x(b)
    a = self
    (a * b.size).zip(b * a.size)
  end
end

a.x b
=> [[1, 4], [2, 5], [3, 6], [1, 4], [2, 5], [3, 6], [1, 4], [2, 5], [3, 6]]

Ryan, this works only if a.size and b.size are relatively prime, as in your first example. The second example shows the error. If you use sort in a different place it should work, though:

   (a * b.size).sort.zip(b * a.size)

Regards,
Pit

class Array

  > def x(b)
  > a = self
  > (a * b.size).zip(b * a.size)
  > end
  > end

  > a.x b
  > => [[1, 4], [2, 5], [3, 6], [1, 4], [2, 5], [3, 6], [1, 4], [2, 5],
  > [3, 6]]

  Thanks for your hint, It seems so simple and pretty.