-
Sep 12th, 2024, 07:48 AM
#1
Thread Starter
Addicted Member
Exit two nested for...
Just curious... Is there a way to exit two nested "for-next" loops without using a "goto" statement to jump over two "nexts", e.g. with "Exit For: Exit For" or something similar?
-
Sep 12th, 2024, 07:56 AM
#2
Re: Exit two nested for...
Code:
For i=0 To 100
Flag = False
For j=0 To 100
If SomeCondition Then
Flag = True
Exit For
End If
Next
If Flag Then Exit For
Next
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 12th, 2024, 08:13 AM
#3
Re: Exit two nested for...
If outer loop is on i variable try passing optional control variable in Exit For i quite similar to Next i construct.
p.s. Wish this was implemented in VB7 or TB. . .
-
Sep 12th, 2024, 08:17 AM
#4
Re: Exit two nested for...
Originally Posted by wqweto
If outer loop is on i variable try passing optional control variable in Exit For i quite similar to Next i construct.
p.s. Wish this was implemented in VB7 or TB. . .
AFAIK, won't work (not supported)
Workaround: Rewrite the outer loop from a For/Next to a Do/Loop
Code:
i=0
Do While i<=100
For j=0 To 100
If SomeCondition Then Exit Do
Next
i=i+1
Loop
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 12th, 2024, 08:18 AM
#5
Re: Exit two nested for...
"Exit For i" produces a "Syntax error" compile error. As far as I know only PHP allows specifying how many nested loops you can break out of (with "break n")...
The evil "GoTo" is still the best way to exit multiple loops. Of course you could always use a boolean variable "bInnerLoop" and set it to True if you need to exit the inner loop prematurely. Then in the outer loop you can do "If bInnerLoop Then Exit For". As you can see, "GoTo" is still better, haha.
Last edited by VanGoghGaming; Sep 12th, 2024 at 08:28 AM.
-
Sep 12th, 2024, 09:03 AM
#6
Re: Exit two nested for...
Originally Posted by VanGoghGaming
As you can see, "GoTo" is still better, haha.
It's not. Period!
I've shown 2 "standard" ways how to do it.
A 3rd way would be to put the nested loops (and just them) into a Sub/Function, and then use "Exit Sub/Function" in the inner loop
How many more ways are needed?
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 12th, 2024, 09:25 AM
#7
Thread Starter
Addicted Member
Re: Exit two nested for...
I wouldn't want to use a "sub/function" or use a "boolean flag". The smartest solution seems to rewrite the outer loop from a "For/Next" to a "Do/Loop".
Zvoni, why are you so determined about not using a "GOTO" to exit? Maybe because it causes confusion in the "stack"?
Or is it an "ideological" problem?
-
Sep 12th, 2024, 09:30 AM
#8
Re: Exit two nested for...
Originally Posted by fabel358
I wouldn't want to use a "sub/function" or use a "boolean flag". The smartest solution seems to rewrite the outer loop from a "For/Next" to a "Do/Loop".
Zvoni, why are you so determined about not using a "GOTO" to exit? Maybe because it causes confusion in the "stack"?
Or is it an "ideological" problem?
In the way the question is posed: ideological
Goto is a sure fire way to produce spaghetti-code, nevermind that you have to do Flow-Control by hand
https://en.wikipedia.org/wiki/Spaghetti_code
https://en.wikipedia.org/wiki/Goto
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 12th, 2024, 09:33 AM
#9
Re: Exit two nested for...
Just another alternative, once you understand how loops work:
Code:
Dim i As Long, j As Long
For i=0 To 100
For j=0 To 100
If SomeCondition Then
i = 100
Exit For
End If
Next
Next
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Sep 12th, 2024, 09:35 AM
#10
Re: Exit two nested for...
Originally Posted by Elroy
Just another alternative, once you understand how loops work:
Code:
Dim i As Long, j As Long
For i=0 To 100
For j=0 To 100
If SomeCondition Then
i = 100
Exit For
End If
Next
Next
OUCH!!
Never ever "manipulate" a Control-Variable of a For-Loop (a.k.a assigning a Value to it within the loop).
It might work in your case, but it's considered bad practice
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 12th, 2024, 09:37 AM
#11
Re: Exit two nested for...
Down at the assembly level all these "Exit Do" and "Exit For" equate to the same jump instruction as "GoTo". The advantage of "GoTo" is that it can bypass an arbitrary number of nested loops and it also has the flexibility of exiting some inner loop but continuing any of the outer loops.
Code:
For i = 0 To 100
For j = 0 To 100
If SomeCondition Then
GoTo NextI
ElseIf SomeOtherCondition Then
GoTo ExitLoops
End If
Next j
' arbitrary extra code
NextI:
Next i
ExitLoops:
-
Sep 12th, 2024, 09:49 AM
#12
Re: Exit two nested for...
Originally Posted by Zvoni
Never ever "manipulate" a Control-Variable of a For-Loop (a.k.a assigning a Value to it within the loop).
It might work in your case, but it's considered bad practice
I wouldn’t mind seeing a discussion of that. I find it useful in several circumstances. And, I’ve never seen a language where that doesn’t work. It certainly works in C-like languages, and Fortran as well.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Sep 12th, 2024, 10:05 AM
#13
Thread Starter
Addicted Member
Re: Exit two nested for...
I know that some people will feel offended by what I'm about to write, but I miss the assembler of the 6510 of the Commodore 64, with the "PHP" and "PLP" instructions you could manipulate the "stack" and solve these problems... with contemporary operating systems, we never get full control of the deep core of our computers.
-
Sep 12th, 2024, 12:19 PM
#14
Re: Exit two nested for...
I don't think its a bad practice at all.
for next is basically a loop and we can manipulate the variables inside the loop without someone screaming bad practice.
similar is:
Code:
x = 0
for I = 1 to X
msgbox "hello"
next I
will just skip the for next since its outside the bound, and similar we can do if we change I. so where the problem? nothing.
and here we can just exit without using exit for at all.
Code:
For a = 1 To 7
For b = 1 To 9
For c = 1 To 14
MsgBox "hello"
a = 7
b = 9
c = 14
Next c
Next b
Next a
-
Sep 12th, 2024, 12:41 PM
#15
Re: Exit two nested for...
Yeah, I thought there might be others who did this.
Personally, I just think of a "For/Next" loop as a "Do/Loop" with an "If" test as the first line of code, and some "auto-incrementing" code at the end of the loop.
Code:
Dim i As Long
For i = 1 To 10
' Do stuff.
Next
versus
Code:
Dim i As Long
i = 1
Do
If i > 10 Then Exit Do
' Do stuff.
i = i + 1
Loop
Using the "For/Next" syntax is just a convenience. But, done as a "Do/Loop", it's more clear as to what's going on, and we could see the potential for manipulating the "control" variable to achieve various objectives, such as exiting an outer-loop (as requested by the OP).
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Sep 12th, 2024, 06:03 PM
#16
Re: Exit two nested for...
i would use a go to every time
the exit do is elegant though
i often design lookups as their own function and use exit function once the value is found from nested loops
Last edited by dz32; Sep 12th, 2024 at 06:09 PM.
-
Sep 12th, 2024, 09:02 PM
#17
Re: Exit two nested for...
I’ve been thinking about this and I must admit that I wouldn’t willy-nilly tamper with the control variable, but this is one case where I would. And, to me, it makes perfect sense.
Also, my strong aversion to GoTo tells me that this case isn’t a good exception for its use, since we do have good alternatives.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Sep 12th, 2024, 09:41 PM
#18
Re: Exit two nested for...
Maybe it worths mentioning that for the special case when you need to exit all the loops... and everything, you can put an Exit Sub (Exit Function, Exit Property).
-
Sep 13th, 2024, 03:12 AM
#19
Re: Exit two nested for...
> Also, my strong aversion to GoTo tells me that this case isn’t a good exception for its use, since we do have good alternatives
Modifying the control variable does not work in all cases where GoTo works always. If you have code in outer loop *after* inner loop this will get executed with your strategy.
Must admit I will use GoTo without a blink of an eye in most cases.
cheers,
</wqw>
-
Sep 13th, 2024, 03:24 AM
#20
Re: Exit two nested for...
Originally Posted by wqweto
If you have code in outer loop *after* inner loop this will get executed with your strategy.
Which you can catch easily with the Boolean-Strategy
You are driving on a highway.....
GoTo: Teleport directly to the Town-Square
Other Strategies: Leave the highway at next exit, follow the road incl. all rules, until you arrive safely
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 13th, 2024, 03:26 AM
#21
Re: Exit two nested for...
very seldom I find myself in situations where I need to exit multiple nested for.
usually I code in a way to avoid such thing, as it looks ugly.
GOTO is usually what I use in those situations. not sure why people don't like that, its primitive but effective and fast.
we do have functions for a reason.
its easy to use to search for stuff or do specific task and just exit the function when done.
for readability we should not create functions that are too large in size.
better to add a few subs/functions with specific functionality with good names,
also, functions that can be used in other locations.
-
Sep 13th, 2024, 03:34 AM
#22
Re: Exit two nested for...
Originally Posted by baka
we do have functions for a reason.
its easy to use to search for stuff or do specific task and just exit the function when done.
for readability we should not create functions that are too large in size.
better to add a few subs/functions with specific functionality with good names,
also, functions that can be used in other locations.
The Power of 10-Rule
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 13th, 2024, 03:34 AM
#23
Re: Exit two nested for...
Originally Posted by Zvoni
GoTo: Teleport directly to the Town-Square
Exit Function: Teleport directly to ring road.
-
Sep 13th, 2024, 03:39 AM
#24
Re: Exit two nested for...
Originally Posted by wqweto
Exit Function: Teleport directly to ring road.
Exactly the reason why i rarely use Exit Sub/Function.
OTOH, Exit Sub/Function translates to "return" in C, though with the addition of possibly setting a return-value (compared to vb6)
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 13th, 2024, 05:12 AM
#25
Re: Exit two nested for...
u know nothing about machine-code. GOTO is used everywhere or u would not be able to create anything complex. try code in assembler without JUMP (JMP).
theres no difference when u use it in basic. basically same thing. just because theres cretins that want to shame GOTO it doesn't mean its bad or wrong. contrary. it show they are smart and use what works the best and not following the sheep.
and loops should NOT have fixed bounds as a rule, it depends on the need. I mostly use dynamic bounds.
that 10-rule is crap.
and exit sub/function/exit do etc are perfect. they are basically GOTO. more perfect that this u can not find. optimizing the function 100%. when done u return NOW and not later with some "sheep" mentality to add whatever crap.
-
Sep 13th, 2024, 05:35 AM
#26
Re: Exit two nested for...
Originally Posted by baka
u know nothing about machine-code. GOTO is used everywhere or u would not be able to create anything complex. try code in assembler without JUMP (JMP).
theres no difference when u use it in basic. basically same thing. just because theres cretins that want to shame GOTO it doesn't mean its bad or wrong. contrary. it show they are smart and use what works the best and not following the sheep.
Well, for me it's like driving a car:
I know how to drive.
I'm not interested how it's build, or which piston fires at what time, or which cogs turn with whatever else
and loops should NOT have fixed bounds as a rule, it depends on the need. I mostly use dynamic bounds.
that 10-rule is crap.
and exit sub/function/exit do etc are perfect. they are basically GOTO. more perfect that this u can not find. optimizing the function 100%. when done u return NOW and not later with some "sheep" mentality to add whatever crap.
Right.... NASA has no clue what they are doing....*sigh*
and you should read the title correctly and COMPLETELY!
The Power of 10: Rules for Developing Safety-Critical Code
I'm out of here.....
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Sep 13th, 2024, 06:55 AM
#27
Re: Exit two nested for...
no, its about sheep-coding. u tell the sheep to avoid something that "can" create issues.
theres no "critical" issues to exit a function, but theres a "critical" issue to leave memory un-released. but VB6 don't suffer from this.
u can not compare C/C++ with VB6. its not the same. learn that.
u maybe think Im going too strong about this. but u are actually insulting me by your logic. and this without even understanding that the guidelines where created to help c programmers.
Im not a C programmer. so why do I need to follow the guidelines? what I can do is follow any VB6-guidelines.
-
Sep 13th, 2024, 08:01 AM
#28
Addicted Member
Re: Exit two nested for...
Those rules are a joke.
Not using goto - I can get, but no recursion? In the same sentence? Just slash and burn.
And the rest, (like "Avoid heap memory allocation") are just as useless. Only for lifeless nerds.
Sorry, these kind of things really make me angry!
-
Sep 13th, 2024, 09:32 AM
#29
Thread Starter
Addicted Member
Re: Exit two nested for...
Wow. Let's not get mad at each other.
I tried using the "Do Loop" for the inner loop, so as to exit with an "Exit For" from the outer loop and an "Exit do" from the innermost loop. However, the result was a slower execution (not much really), perhaps also due to the fact that the "for to" was towards a "len" function and with the "do loop" I either added an assignment of "len" to a "long" variable or each cycle repeats the "len" function.
In the end, I confess that I preferred to exit the loop with the classic "GOTO".
Forgive me those who abhor it.
Many thanks everyones!
-
Sep 13th, 2024, 09:34 AM
#30
Re: Exit two nested for...
You know? Another approach I’ve taken to jump out of nested loops is to use different kinds of loops. For instance, use a For/Next loop for the inner loop and a Do/Loop for the outer. Done that way, an Exit Do gets you out if both of them.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Sep 13th, 2024, 09:40 AM
#31
Re: Exit two nested for...
next, I think we should discuss why Vb6 is clearly superior to .net
-
Sep 13th, 2024, 09:52 AM
#32
Fanatic Member
Re: Exit two nested for...
VB6 "caches" the end value when using "For", but not when using While/Until loops.
This code will only execute "Len" once:
Code:
For i = 1 To Len(s)
' Some code
Next
While this code would execute Len() in each iteration, and therefore would be slower:
Code:
i = 1
Do While i <= Len(s)
' Some code
i = i + 1
Loop
Same with Until:
Code:
i = 1
Do Until i > Len(s)
' Some code
i = i + 1
Loop
You can verify this by replacing Len() with this function:
Code:
Private Function GetLen(ByRef s As String) As Long
Debug.Print "GetLen called"
GetLen = Len(s)
End Function
-
Sep 13th, 2024, 11:52 AM
#33
Thread Starter
Addicted Member
Re: Exit two nested for...
In fact... that's what I was writing.
-
Sep 13th, 2024, 12:26 PM
#34
Fanatic Member
Re: Exit two nested for...
My style is to use a flag and call it bExitFor, example:
Code:
Dim i As Long
Dim j As Long
Dim k As Long
Dim bExitFor As Boolean
For i = 1 To 10
' Some code
For j = 1 To 10
' Some code
For k = 1 To 10
' Some code
Next
If bExitFor Then
Exit For
End If
Next
If bExitFor Then
Exit For
End If
Next
-
Sep 13th, 2024, 12:50 PM
#35
Re: Exit two nested for...
It's hilarious the extent people are willing to go to just to avoid the most straightforward solution which is obviously "GoTo". Also it may not be immediately apparent but "End If" is a separate instruction (and as such it takes CPU time to execute) so it should be avoided whenever possible. Here's a case where an extra "End If" makes a whole lot of difference:
Code:
Private Function ReturnArray() As Byte() ' Function returning a byte array
Dim baData() As Byte
Redim baData(0 To 1000)
If True Then
ReturnArray = baData ' The whole array is being COPIED into the function's return value due to the extra "End If"
End If
End Function
Private Function ReturnArray() As Byte() ' Function returning a byte array
Dim baData() As Byte
Redim baData(0 To 1000)
If True Then ReturnArray = baData ' The array is returned by reference without being copied
End Function
*Edit* - Just tested that and it doesn't work (both examples above result in the array being copied), the array assignment needs to be a single instruction just before "End Function" to avoid the array being copied:
Code:
Private Function ReturnArray() As Byte() ' Function returning a byte array
Dim baData() As Byte
Redim baData(0 To 1000)
ReturnArray = baData ' The array is returned by reference without being copied
End Function
Last edited by VanGoghGaming; Sep 13th, 2024 at 01:05 PM.
-
Sep 13th, 2024, 03:08 PM
#36
Re: Exit two nested for...
but how can it NOT being copied. when u leave the function it will get destroyed?
the reference will point to a non valid pointer. I don't get it.
-
Sep 13th, 2024, 03:19 PM
#37
Re: Exit two nested for...
It's part of VB6's tricks when they enabled functions to return arrays (this wasn't always the case). In order to optimize execution speed, when the last instruction in a function is the array assignment to the function's return value then the array is not copied, only the reference is passed forward and obviously the local array isn't destroyed anymore when it exits the function.
Just tested this and the pvData member of the SafeArray structure stays the same meaning the array wasn't copied.
-
Sep 13th, 2024, 04:00 PM
#38
Re: Exit two nested for...
that sounds great.
instead of using "byref" this looks more clean. knowing this I will look into my current project and see if theres a use.
-
Sep 13th, 2024, 04:01 PM
#39
Fanatic Member
Re: Exit two nested for...
Originally Posted by VanGoghGaming
It's hilarious the extent people are willing to go to just to avoid the most straightforward solution which is obviously "GoTo". Also it may not be immediately apparent but "End If" is a separate instruction (and as such it takes CPU time to execute) so it should be avoided whenever possible. Here's a case where an extra "End If" makes a whole lot of difference:
Code:
Private Function ReturnArray() As Byte() ' Function returning a byte array
Dim baData() As Byte
Redim baData(0 To 1000)
If True Then
ReturnArray = baData ' The whole array is being COPIED into the function's return value due to the extra "End If"
End If
End Function
Private Function ReturnArray() As Byte() ' Function returning a byte array
Dim baData() As Byte
Redim baData(0 To 1000)
If True Then ReturnArray = baData ' The array is returned by reference without being copied
End Function
*Edit* - Just tested that and it doesn't work (both examples above result in the array being copied), the array assignment needs to be a single instruction just before "End Function" to avoid the array being copied:
Code:
Private Function ReturnArray() As Byte() ' Function returning a byte array
Dim baData() As Byte
Redim baData(0 To 1000)
ReturnArray = baData ' The array is returned by reference without being copied
End Function
I checked the disassembly output of the 3 functions that you have posted, and they are virtually identical except in the last part, where VB calls vbaAryCopy() in the first 2 functions, and vbaAryMove() in the last one. So what you are saying is true. Strange, but true.
-
Sep 13th, 2024, 04:11 PM
#40
Re: Exit two nested for...
I think the same happens with Strings. What I don't know if they also need to be assigned in the last line of the functions.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|