Skip to content
Abe Pralle edited this page Sep 7, 2022 · 9 revisions

Syntax

Multi-line

forEach (control)
  statements
endForEach

Single Line

forEach (control) statement; statement; ...

forEach-in

forEach-in With Tables

forEach (value in table)
forEach (value at key in table)

forEach-in With Non-Table Collections

forEach (value in collection [from i1] [step size])
forEach (value at index in collection [from i1] [step size])
forEach (... in varname=collection [from i1] [step size])

forEach-of

forEach-of With Tables

forEach (key of table)

forEach-of With Non-Table Collections

forEach (index of collection [from i1] [step size])
forEach (index of varname=collection [from i1] [step size])

Anonymous forEach

forEach (low..high [step size])
forEach (collection [from i1] [step size])

Inline forEach

(forEach in collection [from ...] [step size])
(forEach of collection [from ...] [step size])

An inline forEach should be part of a larger expression. When the compiler encounters an inline forEach, the current statement is wrapped in a forEach (iterator in/of collection) and the inline forEach expression is replaced with with . See examples below.

Named Collection

Writing varname=collection (e.g. writer=list.rewriter) allows a local reference to the collection to be named and accessed by the body of the loop.

Collection Types

Literal Ranges

low..high
low..<limit
high downTo low
high..>low

Collection Classes

These classes are commonly iterated over with forEach. They each implement one of the Collection Protocols described further below.

  • Lists
  • Tables
  • Strings
  • FileReaders

from

from i1
from low..high
from low..<limit
from high downTo low

from i1 specifies the starting index for accessing a Random Access collection (described below).

from <range> specifies the first and final indices.

A forEach from clause cannot be used with Sequential Access collections.

step

step 2
step n
step -1

step size specifies a step size other than the default of 1.

A negative literal integer used as the step size will cause a Random Access collection to be iterated over in reverse order.

Collection Protocol

A collection in Rogue forEach terms is any object that provides one of the following sets of properties and/or methods, listed here in the order of precedence:

forEach Collection Protocol Interface
Random Access At count:Int32 or count()->Int32, at(index:Int32)->DataType
Random Access Get count:Int32 or count()->Int32, get(index:Int32)->DataType
Sequential Access Read-Another read_another()->DataType?
Sequential Access Has-Another has_another:Logical or has_another()->Logical, read()->DataType
Iterator iterator()->Collection
Reader reader()->Collection

If the collection object implements the Iterator Protocol then the datatype returned by the iterator must in turn implement a Random Access or Sequential Access Collection Protocol; same with the Reader Protocol.

By convention Rogue implements iterators as more efficient but more limited compounds and readers as less efficient but more versatile objects.

Examples

Example forEach Usage

local names = ["Alpha", "Beta", "Gamma"]
forEach (n in names) println n  # Prints: Alpha / Beta / Gamma
println (forEach in names)      # Prints: Alpha / Beta Gamma
forEach (i of names) println i  # Prints: 0 / 1 / 2
println (forEach of names)      # Prints: 0 / 1 / 2
forEach (n at i in names) println "$:$"(i,n)  # Prints: 0:Alpha / 1:Beta / 2:Gamma

forEach (n in names from 1) println n     # Prints: Beta / Gamma
forEach (n in names from 0..1) println n  # Prints: Alpha / Beta
forEach (n in names step 2) println n     # Prints: Alpha / Gamma

forEach (1..3) println "Check"  # Prints: Check / Check / Check
forEach (n in 1..5) println n   # Prints: 1 / 2 / 3 / 4 / 5
println (forEach in 1..5)       # Prints: 1 / 2 / 3 / 4 / 5
forEach (n in 1..5 step 2) println n   # Prints: 1 / 3 / 5

forEach (n in 1..<5) println n   # Prints: 1 / 2 / 3 / 4

forEach (n in 1..<5 step 2) println n   # Prints: 1 / 3

forEach (n in 5 downTo 1) println n          # Prints: 5 / 4 / 3 / 2 / 1
forEach (n in 5 downTo 1 step -2) println n  # Prints: 5 / 3 / 1

Example forEach Collection Implementation

forEach (n at i in FibonacciGen(10)) println "f($) = $" (i,n)

class FibonacciGen( remaining_terms:Int32 )
  PROPERTIES
    current = 0
    next    = 1

  METHODS
    method has_another->Logical
      return remaining_terms?

    method read->Int32
      --remaining_terms
      local result = current
      local sum = current + next
      current = next
      next = sum
      return result
endClass

# Output
f(0) = 0
f(1) = 1
f(2) = 1
f(3) = 2
f(4) = 3
f(5) = 5
f(6) = 8
f(7) = 13
f(8) = 21
f(9) = 34