Iteration Fundamentals in Dart
Loops let a Dart program repeat a block of code without duplicating it, running until a controlling condition becomes false or a collection is exhausted. Dart supports four loop constructs — the classic for loop, for-in for iterating Iterables, while, and do-while — each suited to a different iteration pattern, and choosing the right one communicates intent to future readers of the code. Because Dart compiles to native machine code on mobile and efficient JavaScript on web, tight loops over large collections remain performant, though idiomatic Dart increasingly favors Iterable methods like map and where over manual index-based loops for readability.
Cricket analogy: A bowler running through an entire over repeats the same run-up and delivery action six times, stopping only when the over (the controlling condition) is complete — the same repeat-until-done pattern a Dart loop encodes instead of writing six copies of delivery code.
for, for-in, and while Loops
The classic for loop — for (var i = 0; i < n; i++) — gives full control over the initializer, condition, and increment, making it the right choice when you need the index itself, such as comparing adjacent list elements. The for-in loop iterates directly over any Iterable's elements without exposing an index, which is both more concise and less error-prone since there's no off-by-one risk in a manual increment. A while loop checks its condition before every iteration and is best when the number of repetitions isn't known in advance, such as reading from a stream until a sentinel value appears.
Cricket analogy: A scorer manually tallying runs ball-by-ball uses the delivery index like a for loop's counter — checking ball 1, then 2, then 3 — while simply reading off the list of batsmen who came in to bat is more like a for-in loop that doesn't care about their index.
// Classic for loop with index
var total = 0;
for (var i = 0; i < 5; i++) {
total += i;
}
// for-in over an Iterable
final scores = [88, 92, 79, 95];
for (final score in scores) {
print('Score: $score');
}
// while loop with unknown iteration count
var attempts = 0;
var connected = false;
while (!connected && attempts < 3) {
connected = tryConnect();
attempts++;
}do-while Loops and Loop Control (break, continue)
A do-while loop checks its condition after executing the loop body, guaranteeing at least one execution — useful for patterns like retrying a network request at least once before checking whether to retry again. The break statement exits the nearest enclosing loop immediately, while continue skips the rest of the current iteration and jumps to the next one; both work inside for, for-in, while, and do-while loops, and labeled breaks (like outerLoop: for (...) { break outerLoop; }) let you exit a specific loop from within nested loops.
Cricket analogy: A team always bowls at least one over of a bowler before the captain decides whether to continue with them — a guaranteed-first-run pattern exactly like do-while executing its body once before checking the condition — and a captain calling off a rain-hit match uses break to exit entirely.
Dart supports labeled statements: prefixing a loop with a label like search: and writing break search; inside a nested inner loop lets you exit the outer loop directly, avoiding the awkward boolean 'found' flags often needed in languages without labeled break.
Iterating Collections with forEach and for-in
Iterable.forEach((element) { ... }) applies a function to every element and is functionally similar to for-in, but forEach cannot use break or continue and cannot be paused with an await inside an async function the way a for-in loop with await can, since forEach's callback runs synchronously per call. For most collection traversal, idiomatic Dart favors for-in for its readability and control-flow flexibility, reserving forEach for short, side-effect-only operations like printing or logging each item.
Cricket analogy: Reading out the entire batting lineup to the crowd one name at a time, with no way to stop partway through, is like Iterable.forEach — a fixed, uninterruptible pass — whereas a scorer manually going through the lineup with a for-in loop can stop early the moment a declared total is reached.
final orders = [120.0, 45.5, 300.0, 15.0];
// forEach: no early exit possible
orders.forEach((amount) => print('Order: $amount'));
// for-in: can break early
double runningTotal = 0;
for (final amount in orders) {
runningTotal += amount;
if (runningTotal > 400) {
print('Budget cap reached, stopping.');
break;
}
}Calling break or continue inside a forEach callback is a compile error, not a runtime surprise — the callback is an ordinary function, not loop syntax. If you need to stop iterating early, switch to a for-in loop with an explicit break, or use Iterable methods like takeWhile.
- for gives full control over index, condition, and increment; for-in iterates any Iterable without exposing an index.
- while checks its condition before each iteration; do-while checks after, guaranteeing at least one run.
- break exits the nearest enclosing loop immediately; continue skips to the next iteration.
- Labeled loops (label: for (...) { break label; }) let you exit a specific outer loop from nested loops.
- forEach cannot use break or continue since its callback is an ordinary function, not loop syntax.
- Idiomatic Dart favors for-in and Iterable methods (map, where) over manual index loops for readability.
Practice what you learned
1. Which loop construct guarantees its body executes at least once?
2. What is the key difference between break and continue in a Dart loop?
3. Why can't you use break inside an Iterable.forEach callback?
4. What does a labeled break like break outerLoop; let you do?
5. Which loop is generally preferred in idiomatic Dart for iterating over a List when the index isn't needed?
Was this page helpful?
You May Also Like
Conditionals in Dart
Learn how Dart evaluates branching logic using if/else, switch statements with Dart 3 pattern matching, and compact conditional expressions like the ternary and null-aware operators.
Functions in Dart
Understand how Dart declares functions, its three parameter styles, first-class function values, recursion, and lexical scoping.
Arrow Functions and Closures
Explore Dart's compact arrow (=>) function syntax and how closures capture enclosing variables to power callbacks and higher-order functions.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics