A loop within another loop..

D

Dominic Son

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
 
M

Mike Harris

Dominic said:
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.
 
J

Jan Svitok

Dominic said:
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"
 
S

Snow Man

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top