How to skip an iteration in a FOR loop?

FUNCTION testNext()
	testA = ["apple", 2, "carrot", "dapple", 5, "fapple", "gourd"]
	testInt = 0
	FOR EACH fruit IN testA
		testInt++
		IF TYPE(fruit) = "roString" THEN ? fruit ELSE testA.Next()
		? "testNext() did one step, fruit " fruit ", testInt" testInt
	END FOR
END FUNCTION

This doesn’t do what I want, it increments the counter but doesn’t skip the rest of the loop cycle, and then the counter is incremented AGAIN at the bottom, so “carrot” never prints out, etc. I’d like to avoid using GOTO if possible. Any ideas?

FUNCTION testNext()
   testA = ["apple", 2, "carrot", "dapple", 5, "fapple", "gourd"]
   testInt = 0
   FOR EACH fruit IN testA
      testInt++
      IF TYPE(fruit) = "roString" THEN
           ? fruit
      ELSE
           Next
      END IF
      ? "testNext() did one step, fruit " fruit ", testInt" testInt
   END FOR
END FUNCTION

What exactly are you trying to do? Why are you increment in the for each loop?

FUNCTION testNext()
testA = [“apple”, 2, “carrot”, “dapple”, 5, “fapple”, “gourd”]
for fruit = 0 to testA.count()-1
if type(testA[fruit]) = “roString” ? testA[fruit]
? “testNext(): did one step; fruit=”+testA[fruit].toStr()+" index="+fruit.toStr()
next fruit
END Function

Wouldn’t that be easier.. I mean sorta? Are you just trying to build a string of names of fruit from among a non sorted one dimensional array? What exactly are you trying to do sir.. lol

Is shorter better or does adding that extra reference to the array mean it slows down the code and longer is better. You be the judge. you need a huge array to test the millisecond differences. In a list small as this the difference is NIL.


For some reason the Roku docs do not note the special use of “next varname” as an option.

Take this for example:
for fruit = 0 to testA.count()-1
for potion = 0 to testB.count()-1
for skill = 0 to testC.count()-1

Now at any time we can “Next fruit” or “Next potion” or “Next skill” and not involve the other nested for loops incrementing. Using “End for” will interact with the last nested for. Using “next varname” will increment the loop for the associated varname.

Why isn’t this in the Roku documentation?

@RokuTannerD This is an oversight and should be corrected. You can use “Next varname” when using “For varname=” in a loop. When doing this it allows incrementing nested for’s out of order which the “End for” does not allow. Thanks. ^_~

https://developer.roku.com/docs/references/brightscript/language/program-statements.md

it is that page that is incorrect --^

Also.. why can’t we

For each {varname1 varname2 varname3} in var ? Other languages allow this but not brightscript.

destruk, that gives me:

Syntax Error. (compile error &h02) in pkg:/source/mn.brs(1846)

which is the line with Next

speechles, that’s very interesting about using NEXT Var in place of END FOR.

(The integer increment was just for information on the printout to help me clarify what was going on.)

Basically I’m trying to process objects in an array, and if the object has a certain property, do all the rest of the processing, otherwise I want to skip to the next object. My current solution is to simply make it a huge IF block, indenting over dozens of lines of code, which aesthetically I’d rather not do but it works just fine. So really this thread is more academic and not really important.

“Komag” wrote:
destruk, that gives me:

Syntax Error. (compile error &h02) in pkg:/source/mn.brs(1846)

which is the line with Next
That is odd.  Perhaps they can not be mixed, but all of my loops I write for my own apps use Next instead of End For.
So I’ll need to test and see if replacing End For here with Next resolves that.
Next is a reserved word in brightscript and I was always under the impression they (End For and Next) are interchangeable.

FUNCTION testNext()
   testA = ["apple", 2, "carrot", "dapple", 5, "fapple", "gourd"]
   testInt = 0
   FOR EACH fruit IN testA
      testInt++
      IF TYPE(fruit) = "roString" THEN
           ? fruit
      ELSE
           Next
      END IF
      ? "testNext() did one step, fruit " fruit ", testInt" testInt
   Next
END FUNCTION

NEXT does not work for me inside that if statement. Syntax error.

“squirreltown” wrote:
NEXT does not work for me inside that if statement. Syntax error.
Weird, ok, you are right. It can’t be within the IF statement.
But this works fine if you rewrite the loop slightly. And if you’re wanting the index value of the array for the printed results, you should increment the value after the print statement.

Sub Main()
   testA = ["apple", 2, "carrot", "dapple", 5, "fapple", "gourd"]
   testInt = 0
   FOR EACH fruit IN testA
      IF TYPE(fruit) = "roString" THEN
           ? fruit
	   ? "testNext() did one step, fruit " fruit ", testInt" testInt
      END IF
      testInt++
  Next
End Sub

Just for kicks I tried, and yes, End For can’t be within the If statement either, so it’s consistent. Other languages (like PHP) allow this - next will exit any subsequent nested if statements and increment the internal loop counter and re-execute the inner-most loop, just not brightscript.

Why not just let the loop construct handle the counter:


Sub Main()
   testA = ["apple", 2, "carrot", "dapple", 5, "fapple", "gourd"]
   FOR i = 0 TO testA.Count() - 1
      fruit = testA[i]
      IF TYPE(fruit) = "roString" THEN
           ? i; ": "; fruit
      END IF
    END FOR
End Sub

 0: apple
 2: carrot
 3: dapple
 5: fapple
 6: gourd

My whole point was to NOT process stuff sometimes, so that the counter results would be sequential, such as:

 1: apple
 2: carrot
 3: dapple
 4: fapple
 5: gourd

but apparently that can only be done by working with big IF statements and lots of indenting!

FUNCTION testNext()
   testA = ["apple", 2, "carrot", "dapple", 5, "fapple", "gourd"]
   testInt = 0
   FOR EACH fruit IN testA
      IF TYPE(fruit) = "roString"
         testInt++
         ? "testNext() found a String, fruit " fruit ", testInt" testInt
         ' And do 50 more lines of code,
         ' all indented to be within this huge IF block,
         ' instead of just skipping to next item in list,
         ' too bad
         ' Could maybe use GOTO but that's not something I like to do,
         ' So the IF block with indenting is the lesser of two evils!
      END IF
   END FOR
END FUNCTION

FUNCTION testNext()
testA = [“apple”, 2, “carrot”, “dapple”, 5, “fapple”, “gourd”]
index = 0
while index < testA.count()
fruit = testA[index]
if type(fruit) = “string” then 'do stuff
index++
end while 'wend
END Function

The while/endwhile (while/wend) is probably a better choice. You can iterate the array at any moment you like forward and backwards in any increment. For has a limitation of iteration forward only.

So you know apple has a numeric after it to tell the power of the apple when you eat how much it fills you up. Different apples fill up your hunger differently.

If type(fruit) = “string”
if fruit = “apple”
fill = testA[index+1]
m.hunger -= fill ’ eat the apple
’ skip to next entry and skip value assigned to apple
index +=2

Still not sure what you want to do but If I knew I bet I could figure out how to do what you want.. ^_~

FUNCTION testNext()

   testA = ["apple", 2, "carrot", "dapple", 5, "fapple", "gourd"]
   testInt = 0
   FOR i = 0 to testA.count()-1
        IF TYPE( testA[i]) = "roString"
         testInt++
         ? "testNext() found a String, fruit " testA[i] ", testInt" testInt
        ELSE
        END IF
   END FOR
END FUNCTION

testNext() found a String, fruit apple, testInt 1
testNext() found a String, fruit carrot, testInt 2
testNext() found a String, fruit dapple, testInt 3
testNext() found a String, fruit fapple, testInt 4
testNext() found a String, fruit gourd, testInt 5

“speechles” wrote:
Still not sure what you want to do but If I knew I bet I could figure out how to do what you want.. ^_~
I literally just wanted to avoid indenting a lot of lines in a big IF block.

If I could just disqualify an Item on the list and say “Next” and have it skip the rest of the FOR loop code for this iteration, then the rest of the FOR loop wouldn’t have to be written within an indented IF block, but rather just be lines that are not indented.

Thank you for the WHILE loop example, and I like how it gives more manual control, but the same issue still applies, need to use an indented IF block.

In general, putting large blocks of code inside nested IF statements (or even using multiple nested IF statements) is considered poor programming practice, so you’re on the right track. However, you can easily avoid this by separating out the fruit-processing code into its own function:


Function doFruit(num As Integer, fruit As String)
    ' Do all the fruit processing here ... '
    ? num; ": "; fruit
End Function

Sub Main()
   testA = ["apple", 2, "carrot", "dapple", 5, "fapple", "gourd"]
   num = 0
   For Each fruit In testA
      If Type(fruit) = "roString" Then doFruit(num, fruit) : num++
   End For
End Sub


 0: apple
 1: carrot
 2: dapple
 3: fapple
 4: gourd

EDIT: Put the num++ statement before or after the doFruit() function call depending on whether you want the fruit list to start at 1 or zero.

Yeah, I think that’s probably the best/cleanest approach.