A loop within another loop..

Discussion in 'Ruby' started by Dominic Son, Jan 11, 2007.

  1. Dominic Son

    Dominic Son Guest

    Hi. Hopefully you will see the code and see what I'm trying to do, and
    see the problem. The loop seems messy, but my method to help with eye
    strain is to match up the do-end's down an imaginary column... ie:

    array.each # do # |i|
    puts i # # <-imaginary column
    # end #

    ##### So here's the code. ###########

    def foo(argument1, argument2) #1
    user = [2,5]

    user.each do |bar|
    output = [] #2
    argument1.each do |i| #3

    if i.parent.id == bar.id #4
    output << i.parent.name
    end
    end

    argument2.each do |i|
    if i.parent.id == bar.id
    output << i.name
    end
    end
    return output
    end

    Comments:
    #1 - argument comes in as arrays
    #2 - let's setup the var that will return the array of collected data
    #3 - i think this is where the problem may lie.
    #4 - parent is an acts_as_tree method inside rails, just grabs the
    parant.
    notice how i call the iterating variable 'bar' inside this new
    loop..is this legal?

    My intuition tells me there's probably a better method to do this. Any
    comments, suggestions would be appreciated.

    Dominic

    --
    Posted via http://www.ruby-forum.com/.
     
    Dominic Son, Jan 11, 2007
    #1
    1. Advertising

  2. Dominic Son

    Mike Harris Guest

    Dominic Son wrote:

    >Hi. Hopefully you will see the code and see what I'm trying to do, and
    >see the problem. The loop seems messy, but my method to help with eye
    >strain is to match up the do-end's down an imaginary column... ie:
    >
    >array.each # do # |i|
    > puts i # # <-imaginary column
    > # end #
    >
    >##### So here's the code. ###########
    >
    >def foo(argument1, argument2) #1
    >user = [2,5]
    >
    >user.each do |bar|
    >output = [] #2
    >argument1.each do |i| #3
    >
    > if i.parent.id == bar.id #4
    > output << i.parent.name
    > end
    > end
    >
    > argument2.each do |i|
    > if i.parent.id == bar.id
    > output << i.name
    > end
    > end
    >return output
    > end
    >
    >Comments:
    >#1 - argument comes in as arrays
    >#2 - let's setup the var that will return the array of collected data
    >#3 - i think this is where the problem may lie.
    >#4 - parent is an acts_as_tree method inside rails, just grabs the
    >parant.
    > notice how i call the iterating variable 'bar' inside this new
    >loop..is this legal?
    >
    >My intuition tells me there's probably a better method to do this. Any
    >comments, suggestions would be appreciated.
    >
    >Dominic
    >
    >
    >

    First, your code is missing an end. Second, making the end to the block
    start is easy with the standard convention

    (with the missing end added in)

    def foo(argument1, argument2) #1
    user = [2,5]

    user.each do |bar|
    output = [] #2
    argument1.each do |i| #3
    if i.parent.id == bar.id #4
    output << i.parent.name
    end
    end
    end

    argument2.each do |i|
    if i.parent.id == bar.id
    output << i.name
    end
    end

    output
    end

    This is infinitely easier (to me, and 99.9% of programmers) than moving
    the end out to match the do. Do you find this hard to read? You seem
    to have no problem matching the end to its matching if.
     
    Mike Harris, Jan 11, 2007
    #2
    1. Advertising

  3. Dominic Son

    Jan Svitok Guest

    On 1/11/07, Mike Harris <> wrote:
    > Dominic Son wrote:
    >
    > >Hi. Hopefully you will see the code and see what I'm trying to do, and
    > >see the problem. The loop seems messy, but my method to help with eye
    > >strain is to match up the do-end's down an imaginary column... ie:
    > >
    > >array.each # do # |i|
    > > puts i # # <-imaginary column
    > > # end #
    > >
    > >##### So here's the code. ###########
    > >
    > >def foo(argument1, argument2) #1
    > >user = [2,5]
    > >
    > >user.each do |bar|
    > >output = [] #2
    > >argument1.each do |i| #3
    > >
    > > if i.parent.id == bar.id #4
    > > output << i.parent.name
    > > end
    > > end
    > >
    > > argument2.each do |i|
    > > if i.parent.id == bar.id
    > > output << i.name
    > > end
    > > end
    > >return output
    > > end
    > >
    > >Comments:
    > >#1 - argument comes in as arrays
    > >#2 - let's setup the var that will return the array of collected data
    > >#3 - i think this is where the problem may lie.
    > >#4 - parent is an acts_as_tree method inside rails, just grabs the
    > >parant.
    > > notice how i call the iterating variable 'bar' inside this new
    > >loop..is this legal?
    > >
    > >My intuition tells me there's probably a better method to do this. Any
    > >comments, suggestions would be appreciated.
    > >
    > >Dominic
    > >
    > >
    > >

    > First, your code is missing an end. Second, making the end to the block
    > start is easy with the standard convention
    >
    > This is infinitely easier (to me, and 99.9% of programmers) than moving
    > the end out to match the do. Do you find this hard to read? You seem
    > to have no problem matching the end to its matching if.


    1. The main question: is this legal - yes, it's perfectly legal, it's
    one of the blocks' features. The blocks are closures, i.e. they keep
    they outer context. This is used when you pass a block between
    functions:

    def fun2
    yield 10
    end

    def fun1
    a= 5
    puts fun2 do |i| # yield 10 will set i=10
    i + a # here block has access to a even though it is called from fun2
    end # => 15
    end

    2. few changes to the code:
    (I changed bar.id to just bar - it seems to me that's what you want)

    def foo(argument1, argument2)
    user = [2,5]
    output = []
    user.each do |bar|
    output += argument1.select{|i| i.parent.id == bar}.map{|i|
    i.parent.name}
    output += argument2.select{|i| i.parent.id == bar}.map{|i| i.name}
    end
    output
    end

    see Enumerable#select, Enumerable#map for explanation.
    shortly: "from argument1 array select those that fulfill the condition
    and for each of them get i.parent.name"
     
    Jan Svitok, Jan 11, 2007
    #3
  4. Dominic Son

    Snow Man Guest

    Are you sure your code does what you want? It looks like your
    "user.each" block returns after the first iteration and never gets to
    the second one. It might help if you formatted your code in a more
    conventional way in your post.

    --
    Posted via http://www.ruby-forum.com/.
     
    Snow Man, Jan 12, 2007
    #4
    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. KatB
    Replies:
    0
    Views:
    449
  2. takayuki
    Replies:
    2
    Views:
    280
    Calvin Spealman
    Jun 16, 2008
  3. takayuki
    Replies:
    17
    Views:
    472
    John Salerno
    Jun 17, 2008
  4. addi
    Replies:
    0
    Views:
    271
  5. Isaac Won
    Replies:
    9
    Views:
    383
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page