Documentation update for Iterable class

Contains:
- Examples

Closes https://github.com/dart-lang/sdk/pull/47845
https://github.com/dart-lang/sdk/pull/47845

GitOrigin-RevId: ba3b885224b2511be2b06148d16bd6d3622473d9
Change-Id: Iadc197183b6464d66527701ba71978c8d9ac683a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/222023
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 0b42ab7..41d7e23 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -162,6 +162,13 @@
   /// The returned iterable will provide the same elements as this iterable,
   /// and, after that, the elements of [other], in the same order as in the
   /// original iterables.
+  ///
+  /// Example:
+  /// ```dart
+  /// var planets = <String>['Earth', 'Jupiter'];
+  /// var updated = planets.followedBy(['Mars', 'Venus']);
+  /// print(updated); // (Earth, Jupiter, Mars, Venus)
+  /// ```
   Iterable<E> followedBy(Iterable<E> other) {
     var self = this; // TODO(lrn): Remove when we can promote `this`.
     if (self is EfficientLengthIterable<E>) {
@@ -189,13 +196,24 @@
   /// For example, [elementAt] may call `toElement` only once.
   ///
   /// Equivalent to:
-  /// ```dart
+  /// ```
   /// Iterable<T> map<T>(T toElement(E e)) sync* {
   ///   for (var value in this) {
   ///     yield toElement(value);
   ///   }
   /// }
   /// ```
+  /// Example:
+  /// ```dart import:convert
+  /// var products = jsonDecode('''
+  /// [
+  ///   {"name": "Screwdriver", "price": 42.00},
+  ///   {"name": "Wingnut", "price": 0.50}
+  /// ]
+  /// ''');
+  /// var values = products.map((product) => product['price'] as double);
+  /// var totalPrice = values.fold(0.0, (a, b) => a + b); // 42.5.
+  /// ```
   Iterable<T> map<T>(T toElement(E e)) => MappedIterable<E, T>(this, toElement);
 
   /// Returns a new lazy [Iterable] with all elements that satisfy the
@@ -210,6 +228,14 @@
   /// Iterating will not cache results, and thus iterating multiple times over
   /// the returned [Iterable] may invoke the supplied
   /// function [test] multiple times on the same element.
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// var result = numbers.where((x) => x < 5); // (1, 2, 3)
+  /// result = numbers.where((x) => x > 5); // (6, 7)
+  /// result = numbers.where((x) => x.isEven); // (2, 6)
+  /// ```
   Iterable<E> where(bool test(E element)) => WhereIterable<E>(this, test);
 
   /// Returns a new lazy [Iterable] with all elements that have type [T].
@@ -233,17 +259,18 @@
   ///
   /// Example:
   /// ```dart
-  /// var pairs = [[1, 2], [3, 4]];
-  /// var flattened = pairs.expand((pair) => pair).toList();
-  /// print(flattened); // => [1, 2, 3, 4];
+  /// Iterable<int> count(int n) sync* {
+  ///   for (var i = 1; i <= n; i++) {
+  ///     yield i;
+  ///    }
+  ///  }
   ///
-  /// var input = [1, 2, 3];
-  /// var duplicated = input.expand((i) => [i, i]).toList();
-  /// print(duplicated); // => [1, 1, 2, 2, 3, 3]
+  /// var numbers = [1, 3, 0, 2];
+  /// print(numbers.expand(count)); // (1, 1, 2, 3, 1, 2)
   /// ```
   ///
   /// Equivalent to:
-  /// ```dart
+  /// ```
   /// Iterable<T> expand<T>(Iterable<T> toElements(E e)) sync* {
   ///   for (var value in this) {
   ///     yield* toElements(value);
@@ -267,6 +294,15 @@
   /// (see [Set.identity]) that its `contains` uses.
   /// Likewise the `Iterable` returned by a [Map.keys] call
   /// should use the same equality that the `Map` uses for keys.
+  ///
+  /// Example:
+  /// ```dart
+  /// final gasPlanets = <int, String>{1: 'Jupiter', 2: 'Saturn'};
+  /// final containsOne = gasPlanets.keys.contains(1); // true
+  /// final containsFive = gasPlanets.keys.contains(5); // false
+  /// final containsJupiter = gasPlanets.values.contains('Jupiter'); // true
+  /// final containsMercury = gasPlanets.values.contains('Mercury'); // false
+  /// ```
   bool contains(Object? element) {
     for (E e in this) {
       if (e == element) return true;
@@ -275,6 +311,16 @@
   }
 
   /// Invokes [action] on each element of this iterable in iteration order.
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 6, 7];
+  /// numbers.forEach(print);
+  /// // 1
+  /// // 2
+  /// // 6
+  /// // 7
+  /// ```
   void forEach(void action(E element)) {
     for (E element in this) action(element);
   }
@@ -288,7 +334,7 @@
   /// Otherwise this method starts with the first element from the iterator,
   /// and then combines it with the remaining elements in iteration order,
   /// as if by:
-  /// ```dart
+  /// ```
   /// E value = iterable.first;
   /// iterable.skip(1).forEach((element) {
   ///   value = combine(value, element);
@@ -297,7 +343,9 @@
   /// ```
   /// Example of calculating the sum of an iterable:
   /// ```dart
-  /// iterable.reduce((value, element) => value + element);
+  /// final numbers = <double>[10, 2, 5, 0.5];
+  /// final result = numbers.reduce((value, element) => value + element);
+  /// print(result); // 17.5
   /// ```
   E reduce(E combine(E value, E element)) {
     Iterator<E> iterator = this.iterator;
@@ -317,7 +365,7 @@
   /// Uses [initialValue] as the initial value,
   /// then iterates through the elements and updates the value with
   /// each element using the [combine] function, as if by:
-  /// ```dart
+  /// ```
   /// var value = initialValue;
   /// for (E element in this) {
   ///   value = combine(value, element);
@@ -326,7 +374,11 @@
   /// ```
   /// Example of calculating the sum of an iterable:
   /// ```dart
-  /// iterable.fold(0, (prev, element) => prev + element);
+  /// final numbers = <double>[10, 2, 5, 0.5];
+  /// const initialValue = 100.0;
+  /// final result = numbers.fold<double>(
+  ///     initialValue, (previousValue, element) => previousValue + element);
+  /// print(result); // 117.5
   /// ```
   T fold<T>(T initialValue, T combine(T previousValue, E element)) {
     var value = initialValue;
@@ -338,6 +390,14 @@
   ///
   /// Checks every element in iteration order, and returns `false` if
   /// any of them make [test] return `false`, otherwise returns `true`.
+  ///
+  /// Example:
+  /// ```dart
+  /// final planetsByMass = <double, String>{0.06: 'Mercury', 0.81: 'Venus',
+  ///   0.11: 'Mars'};
+  /// // Checks whether all keys are smaller than 1.
+  /// final every = planetsByMass.keys.every((key) => key < 1.0); // true
+  /// ```
   bool every(bool test(E element)) {
     for (E element in this) {
       if (!test(element)) return false;
@@ -351,6 +411,13 @@
   /// converts each one to a [String] by calling [Object.toString],
   /// and then concatenates the strings, with the
   /// [separator] string interleaved between the elements.
+  ///
+  /// Example:
+  /// ```dart
+  /// final planetsByMass = <double, String>{0.06: 'Mercury', 0.81: 'Venus',
+  ///   0.11: 'Mars'};
+  /// final joinedNames = planetsByMass.values.join('-'); // Mercury-Venus-Mars
+  /// ```
   String join([String separator = ""]) {
     Iterator<E> iterator = this.iterator;
     if (!iterator.moveNext()) return "";
@@ -373,6 +440,13 @@
   ///
   /// Checks every element in iteration order, and returns `true` if
   /// any of them make [test] return `true`, otherwise returns false.
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// var result = numbers.any((element) => element >= 5); // true;
+  /// result = numbers.any((element) => element >= 10); // false;
+  /// ```
   bool any(bool test(E element)) {
     for (E element in this) {
       if (test(element)) return true;
@@ -384,6 +458,14 @@
   ///
   /// The elements are in iteration order.
   /// The list is fixed-length if [growable] is false.
+  ///
+  /// Example:
+  /// ```dart
+  /// final planets = <int, String>{1: 'Mercury', 2: 'Venus', 3: 'Mars'};
+  /// final keysList = planets.keys.toList(growable: false); // [1, 2, 3]
+  /// final valuesList =
+  ///     planets.values.toList(growable: false); // [Mercury, Venus, Mars]
+  /// ```
   List<E> toList({bool growable = true}) {
     return List<E>.of(this, growable: growable);
   }
@@ -395,6 +477,12 @@
   /// or it contains one or more elements that are equal.
   /// The order of the elements in the set is not guaranteed to be the same
   /// as for the iterable.
+  ///
+  /// Example:
+  /// ```dart
+  /// final planets = <int, String>{1: 'Mercury', 2: 'Venus', 3: 'Mars'};
+  /// final valueSet = planets.values.toSet(); // {Mercury, Venus, Mars}
+  /// ```
   Set<E> toSet() => Set<E>.of(this);
 
   /// Returns the number of elements in [this].
@@ -415,11 +503,25 @@
   /// Whether this collection has no elements.
   ///
   /// May be computed by checking if `iterator.moveNext()` returns `false`.
+  ///
+  /// Example:
+  /// ```dart
+  /// final emptyList = <int>[];
+  /// print(emptyList.isEmpty); // true;
+  /// print(emptyList.iterator.moveNext()); // false
+  /// ```
   bool get isEmpty => !iterator.moveNext();
 
   /// Whether this collection has at least one element.
   ///
   /// May be computed by checking if `iterator.moveNext()` returns `true`.
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>{1, 2, 3};
+  /// print(numbers.isNotEmpty); // true;
+  /// print(numbers.iterator.moveNext()); // true
+  /// ```
   bool get isNotEmpty => !isEmpty;
 
   /// Returns a lazy iterable of the [count] first elements of this iterable.
@@ -431,6 +533,13 @@
   /// elements have been seen.
   ///
   /// The `count` must not be negative.
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// final result = numbers.take(4); // (1, 2, 3, 5)
+  /// final takeAll = numbers.take(100); // (1, 2, 3, 5, 6, 7)
+  /// ```
   Iterable<E> take(int count) {
     return TakeIterable<E>(this, count);
   }
@@ -443,6 +552,15 @@
   /// The elements can be computed by stepping through [iterator] until an
   /// element is found where `test(element)` is false. At that point,
   /// the returned iterable stops (its `moveNext()` returns false).
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// var result = numbers.takeWhile((x) => x < 5); // (1, 2, 3)
+  /// result = numbers.takeWhile((x) => x != 3); // (1, 2)
+  /// result = numbers.takeWhile((x) => x != 4); // (1, 2, 3, 5, 6, 7)
+  /// result = numbers.takeWhile((x) => x.isOdd); // (1)
+  /// ```
   Iterable<E> takeWhile(bool test(E value)) {
     return TakeWhileIterable<E>(this, test);
   }
@@ -460,6 +578,13 @@
   /// through earlier elements, for example when iterating a [List].
   /// Such iterables are allowed to ignore the initial skipped elements.
   ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// final result = numbers.skip(4); // (6, 7)
+  /// final skipAll = numbers.skip(100); // () - no elements.
+  /// ```
+  ///
   /// The [count] must not be negative.
   Iterable<E> skip(int count) {
     return SkipIterable<E>(this, count);
@@ -475,6 +600,15 @@
   /// true. If all elements satisfy `test` the resulting iterable is empty,
   /// otherwise it iterates the remaining elements in their original order,
   /// starting with the first element for which `test(element)` returns `false`.
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// var result = numbers.skipWhile((x) => x < 5); // (5, 6, 7)
+  /// result = numbers.skipWhile((x) => x != 3); // (3, 5, 6, 7)
+  /// result = numbers.skipWhile((x) => x != 4); // ()
+  /// result = numbers.skipWhile((x) => x.isOdd); // (2, 3, 5, 6, 7)
+  /// ```
   Iterable<E> skipWhile(bool test(E value)) {
     return SkipWhileIterable<E>(this, test);
   }
@@ -527,6 +661,15 @@
   ///
   /// Iterates through elements and returns the first to satisfy [test].
   ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// var result = numbers.firstWhere((element) => element < 5); // 1
+  /// result = numbers.firstWhere((element) => element > 5); // 6
+  /// result =
+  ///     numbers.firstWhere((element) => element > 10, orElse: () => -1); // -1
+  /// ```
+  ///
   /// If no element satisfies [test], the result of invoking the [orElse]
   /// function is returned.
   /// If [orElse] is omitted, it defaults to throwing a [StateError].
@@ -547,6 +690,15 @@
   /// checks `test(element)` for each,
   /// and finally returns that last one that matched.
   ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// var result = numbers.lastWhere((element) => element < 5); // 3
+  /// result = numbers.lastWhere((element) => element > 5); // 7
+  /// result = numbers.lastWhere((element) => element > 10,
+  ///     orElse: () => -1); // -1
+  /// ```
+  ///
   /// If no element satisfies [test], the result of invoking the [orElse]
   /// function is returned.
   /// If [orElse] is omitted, it defaults to throwing a [StateError].
@@ -571,6 +723,22 @@
   /// If more than one matching element is found, throws [StateError].
   /// If no matching element is found, returns the result of [orElse].
   /// If [orElse] is omitted, it defaults to throwing a [StateError].
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[2, 2, 10];
+  /// var result = numbers.singleWhere((element) => element > 5); // 10
+  /// ```
+  /// When no matching element is found, the result of calling [orElse] is
+  /// returned instead.
+  /// ```dart continued
+  /// result = numbers.singleWhere((element) => element == 1,
+  ///     orElse: () => -1); // -1
+  /// ```
+  /// There must not be more than one matching element.
+  /// ```dart continued
+  /// result = numbers.singleWhere((element) => element == 2); // Throws Error.
+  /// ```
   E singleWhere(bool test(E element), {E orElse()?}) {
     late E result;
     bool foundMatching = false;
@@ -597,6 +765,12 @@
   /// May iterate through the elements in iteration order, ignoring the
   /// first [index] elements and then returning the next.
   /// Some iterables may have a more efficient way to find the element.
+  ///
+  /// Example:
+  /// ```dart
+  /// final numbers = <int>[1, 2, 3, 5, 6, 7];
+  /// final elementAt = numbers.elementAt(4); // 6
+  /// ```
   E elementAt(int index) {
     RangeError.checkNotNegative(index, "index");
     int elementIndex = 0;