Looping: for-in and forEach
on Monday, 20th of July, 2020
Lists (and iterables and sets) are the primary objects that you'll loop over. You can see basic examples of for, while and do-while loops in the Loops lesson in the Control Flow section. Here, let's take a deeper look at two other looping mechanisms: for-in loops and the forEach method on iterables.
Both are used for the same purpose: performing an action on each element in the list. Importantly, both are used primarily for side effects. The original list will not be changed, nor will you be returned any new value from these methods.
for-in loops
For-in loops function similarly to standard for loops, but there are two differences:
1. It easier to write.
2. You won't have access, by default, to the index of the element in the list.
For-in loops are preferable to for loops to me, because they are cleaner, but they don't really solve any problem that standard for loops wont.
This example shows the syntax for for-in loops, but as you can see there is no built-in way to get the index of the element in the list. It
void main() {
List ages = [29, 27, 42];
for (var age in ages) {
print(age);
}
}
forEach
List.forEach is a looping mechanism that is more difficult to grasp (if you aren't familiar with call backs), and provides very little benefit over using a for-loop.
It's best to just look at some code:
void main() {
List ages = [29, 27, 42];
// the arguement that forEach expects is
// a *call back*. This function will be called on
// each element
ages.forEach((int age) => print(age));
}
That looks a bit more complex, but does the exact same thing as the first example using for-in loop. In fact, look at this example comparing the two.
void main() {
List ages = [29, 27, 42];
// should print 30, 28, 43
for (var age in ages) {
_addAndPrint(age);
}
// should print 30, 28, 43
ages.forEach((int age) => _addAndPrint(age));
}
void _addAndPrint(int number) {
print(1 + number);
}
While for-each is more complex to write, it's often favored because of how terse the code looks. For our purposed, it's important because many of the future methods we'll explore on lists and iterables follows this same pattern.