Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
To Nest or Not to Nest Else
#1
Other than code efficiency, I'm wondering why I would nest an Else statement v's using multiple ElseIf statements. You guys nest your Elses? or go with ElseIF's
For example"

NESTED ELSE
If (condition) then
 ....

Else
  If (condition) then
....
     Else
      If (condition) then
....
        Else
         If (condition) then

        End if
   End if
End if

UNNESTED ElseIF
If (condition) then
 ....

ElseIf (condition) then
....

ElseIf (condition) then
....

ElseIf (condition) then
...

End if
  
Just curious
Reply
#2
In such cases, I try to go with SELECT CASE, nested between IF statements, just for the difference in visibility of flow for me.

Too many  ELSEIFs, and I get lost trying to track and keep up with them all.   Instead, I'll swap to independent IFs and GOTOs, to keep my brain organized better.

IF (condition) THEN
   stuff
   GOTO done_iffing_around
END IF

IF (next condition...
    same

IF (same for 4 more ELSEIF type things...
    same
END IF

done_iffing_around:
Reply
#3
I depends on the situation I suppose. Take this rectangular collision code for example:

    IF R1.right >= R2.left THEN '            check for overlapping coordinates
        IF R1.left <= R2.right THEN
            IF R1.bottom >= R2.top THEN
                IF R1.top <= R2.bottom THEN ' all checks passed, must be a collision
                    RectCollide% = -1 '                return that a collision was detected (TRUE)
                END IF
            END IF
        END IF
    END IF

ELSEIF would not work in this case. Also, at any point one of the IF statements becomes FALSE the remaining IF statements are skipped, speeding up the process.

I'm with Steve on this as well. For a situation where many ELSEIFs are required I would rather use SELECT CASE because of its clean style and easy readability.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply
#4
(08-17-2024, 03:35 PM)SMcNeill Wrote: In such cases, I try to go with SELECT CASE, nested between IF statements, just for the difference in visibility of flow for me.

Too many  ELSEIFs, and I get lost trying to track and keep up with them all.   Instead, I'll swap to independent IFs and GOTOs, to keep my brain organized better.

IF (condition) THEN
   stuff
   GOTO done_iffing_around
END IF

IF (next condition...
    same

IF (same for 4 more ELSEIF type things...
    same
END IF

done_iffing_around:

GoTo???  Wash yer mouth out! 
I've gotten the impression I'm about the only one who uses this outdated command!  Big Grin
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Please visit my Website at: http://oldendayskids.blogspot.com/
Reply
#5
I tend to use SELECT CASE whenever possible so I don't if it up too much. It has that neat SELECT EVERYCASE, too. My next favorite is the ELSEIF, which is useful in some situations. I have done some routines like Terry's example with block nested If/then statements and They are easy enough to read and understand, due to the progressive indenting.

Pete
Shoot first and shoot people who ask questions, later.
Reply
#6
I think Terry your nested IF statements would only perform the next test IF the last one was true. Otherwise, as you point out, IF any of the conditions test False no other conditions are tested.

I'm thinking if your code did include Else in the nesting then I think all the conditions would be tested...I think... 


IF R1.right >= R2.left THEN '            check for overlapping coordinates
   Else
     IF R1.left <= R2.right THEN
       Else
            IF R1.bottom >= R2.top THEN
               Else
                   IF R1.top <= R2.bottom THEN ' all checks passed, must be a collision
                    RectCollide% = -1 '                return that a collision was detected (TRUE)
                END IF
            END IF
        END IF
    END IF


IF R1.right >= R2.left THEN '            check for overlapping coordinates
ElseIF R1.left <= R2.right THEN
ElseIF R1.bottom >= R2.top THEN
ElseIF R1.top <= R2.bottom THEN ' all checks passed, must be a collision
                    RectCollide% = -1 '                return that a collision was detected (TRUE)
END IF
   

Both Else and ElseIF would test each condition, without the Else or ElseIF conditions are tested until a False is incurred....I thinks that's correct. Your code would short circuit the IF run and that could save a lot of time in processing
Reply
#7
This was actually a very interesting exercise in backwards logic. @TerryRitchie @Dimster -- Both of you see if this kind of odd scenario appeals to you:

Code: (Select All)
Screen _NewImage(640, 480, 32)
$Color:32
Do
Cls
Line (100, 100)-(200, 200), Red, BF
Line (300, 100)-(400, 200), Blue, BF

While _MouseInput: Wend
x = _MouseX: y = _MouseY
If x >= 100 Then
If x <= 200 Then
If y >= 100 Then
If y <= 200 Then
_PrintString (140, 140), "OK!"
End If
End If
End If
End If

If x < 300 Then
ElseIf x > 400 Then
ElseIf y < 100 Then
ElseIf y > 200 Then
Else
_PrintString (340, 140), "OK!"
End If

_Limit 30
_Display
Loop Until _MouseButton(1)

Run that. There's two boxes on the screen and we check mouse collision with each of them.

The left box uses Terry's style collision to see if the mouse is inside the box or not. For it to trigger, the mouse must be inside each x/y bound.

The right box uses If and ElseIf to exclude the *outsides* of the box, so that the final ELSE has to be the only points left that aren't excluded by our X/Y bounds.

Both works, but the second is so foreign to my usual way of thinking that it blows my mind. We're literally "thinking outside the box" here! Big Grin
Reply
#8
That's pretty cool Steve.
Reply
#9
Well jus ah dadburn minute there ya galoots...

How's about SELECT CASEY?

Code: (Select All)
Screen _NewImage(640, 480, 32)
$Color:32
Do
    Cls
    Line (100, 100)-(200, 200), Red, BF
    Line (300, 100)-(400, 200), Blue, BF
    While _MouseInput: Wend
    x = _MouseX: y = _MouseY

    Select Case x
        Case 100 To 200
            Select Case y
                Case 100 To 200
                    _PrintString (130, 140), "Pete!"
            End Select
    End Select

    If x < 300 Then
    ElseIf x > 400 Then
    ElseIf y < 100 Then
    ElseIf y > 200 Then
    Else
        _PrintString (330, 140), "Steve"
    End If

    _Limit 30
    _Display
Loop Until _MouseButton(1)

- Sam
Shoot first and shoot people who ask questions, later.
Reply
#10
That second method caused my brain to get stuck in an infinite loop ... or it possibly divided by 0, I can't tell which, LOL

Yeah, that's odd looking but works.

Way to butcher SELECT CASE Pete! But hey, it works too.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Reply




Users browsing this thread: 4 Guest(s)