Noob: The ruby way to multiple Array by multiple?

Discussion in 'Ruby' started by Eric Luo, Mar 28, 2006.

  1. Eric Luo

    Eric Luo Guest

    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 :eek:rig_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, Mar 28, 2006
    #1
    1. Advertising

  2. 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 :eek:rig_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
     
    Robert Klemme, Mar 28, 2006
    #2
    1. Advertising

  3. Eric Luo

    Ryan Davis Guest

    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.


    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]]

    --

    http://www.zenspider.com/seattle.rb - Seattle.rb
    http://blog.zenspider.com/
     
    Ryan Davis, Mar 28, 2006
    #3
  4. Eric Luo

    Pit Capitain Guest

    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
     
    Pit Capitain, Mar 28, 2006
    #4
  5. Eric Luo

    Eric Luo Guest

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

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

    Thanks for your hint, It seems so simple and pretty.
     
    Eric Luo, Mar 29, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. anti-guru
    Replies:
    2
    Views:
    7,856
    anti-guru
    Sep 2, 2004
  2. user
    Replies:
    21
    Views:
    751
    Lasse Reichstein Nielsen
    Jul 20, 2006
  3. kj
    Replies:
    2
    Views:
    247
  4. Philip Amadeo Saeli

    Noob Q: ruby block scoping question (ruby TK)

    Philip Amadeo Saeli, Apr 30, 2008, in forum: Ruby
    Replies:
    4
    Views:
    143
    Joel VanderWerf
    May 1, 2008
  5. Jonas Smith
    Replies:
    3
    Views:
    92
    Jonas Smith
    Jun 6, 2008
Loading...

Share This Page