ZetCode

Dart Iterator

last modified April 4, 2025

In Dart, the Iterator interface provides a way to access elements of a collection sequentially. It is fundamental to Dart's iteration mechanism.

The Iterator interface has two key methods: moveNext and current. Most collections implement Iterable which provides an iterator.

Basic Iterator Usage

This example shows the fundamental way to use an iterator manually.

main.dart
void main() {
  var numbers = [1, 2, 3, 4, 5];
  var iterator = numbers.iterator;
  
  while (iterator.moveNext()) {
    print(iterator.current);
  }
}

We create an iterator from a list and use moveNext() to advance through elements. The current property gives the current element. This is how for-in loops work internally.

$ dart main.dart
1
2
3
4
5

Custom Iterator Implementation

This example demonstrates creating a custom class that implements Iterator.

main.dart
class Countdown implements Iterator<int> {
  int _current = 5;
  
  @override
  int get current => _current;
  
  @override
  bool moveNext() {
    if (_current > 0) {
      _current--;
      return true;
    }
    return false;
  }
}

void main() {
  var countdown = Countdown();
  
  while (countdown.moveNext()) {
    print(countdown.current);
  }
}

We implement the Iterator interface with a countdown from 5 to 0. moveNext() decrements _current until it reaches 0. The current getter returns the value.

$ dart main.dart
4
3
2
1
0

Iterable with Iterator

This example shows how to create a custom Iterable class that provides an iterator.

main.dart
class FibonacciSequence implements Iterable<int> {
  final int count;
  
  FibonacciSequence(this.count);
  
  @override
  Iterator<int> get iterator => _FibonacciIterator(count);
}

class _FibonacciIterator implements Iterator<int> {
  final int count;
  int _current = 0;
  int _next = 1;
  int _position = 0;
  
  _FibonacciIterator(this.count);
  
  @override
  int get current => _current;
  
  @override
  bool moveNext() {
    if (_position < count) {
      var newNext = _current + _next;
      _current = _next;
      _next = newNext;
      _position++;
      return true;
    }
    return false;
  }
}

void main() {
  var fib = FibonacciSequence(7);
  
  for (var num in fib) {
    print(num);
  }
}

We create a Fibonacci sequence generator. The Iterable provides an iterator that generates numbers. This allows the class to be used in for-in loops.

$ dart main.dart
1
1
2
3
5
8
13

Iterator with Complex Objects

This example shows using an iterator with a collection of custom objects.

main.dart
class Book {
  final String title;
  final String author;
  
  Book(this.title, this.author);
  
  @override
  String toString() => '$title by $author';
}

class Library implements Iterable<Book> {
  final List<Book> _books = [];
  
  void add(Book book) => _books.add(book);
  
  @override
  Iterator<Book> get iterator => _books.iterator;
}

void main() {
  var library = Library();
  library.add(Book('Dart in Action', 'Manning'));
  library.add(Book('Flutter in Action', 'Manning'));
  library.add(Book('Effective Dart', 'Google'));
  
  var iterator = library.iterator;
  while (iterator.moveNext()) {
    print(iterator.current);
  }
}

We create a Library class that holds Books and implements Iterable. The iterator comes from the underlying List. This pattern is common in collection classes.

$ dart main.dart
Dart in Action by Manning
Flutter in Action by Manning
Effective Dart by Google

Iterator Utilities

This example demonstrates useful iterator utilities like takeWhile and skipWhile.

main.dart
void main() {
  var numbers = [1, 3, 5, 2, 4, 6, 8, 7];
  var iterator = numbers.iterator;
  
  print('Numbers while odd:');
  var oddIterator = numbers.takeWhile((n) => n.isOdd).iterator;
  while (oddIterator.moveNext()) {
    print(oddIterator.current);
  }
  
  print('\nNumbers after first even:');
  var afterEven = numbers.skipWhile((n) => n.isOdd).iterator;
  while (afterEven.moveNext()) {
    print(afterEven.current);
  }
}

We use takeWhile to get elements until a condition fails, and skipWhile to skip elements until a condition fails. These methods return new iterators.

$ dart main.dart
Numbers while odd:
1
3
5

Numbers after first even:
2
4
6
8
7

Best Practices

Source

Dart Iterator Documentation

This tutorial covered Dart's Iterator interface with practical examples showing basic usage, custom implementations, and common patterns.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Dart tutorials.