Skip to content

Commit 1c1f518

Browse files
jpsiitonenCommit Bot
authored andcommitted
Documentation update for Iterable class
Contains: - Examples Closes dart-lang/sdk#47845 dart-lang/sdk#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>
1 parent 7bcce30 commit 1c1f518

File tree

1 file changed

+187
-13
lines changed

1 file changed

+187
-13
lines changed

sdk/lib/core/iterable.dart

Lines changed: 187 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,13 @@ abstract class Iterable<E> {
162162
/// The returned iterable will provide the same elements as this iterable,
163163
/// and, after that, the elements of [other], in the same order as in the
164164
/// original iterables.
165+
///
166+
/// Example:
167+
/// ```dart
168+
/// var planets = <String>['Earth', 'Jupiter'];
169+
/// var updated = planets.followedBy(['Mars', 'Venus']);
170+
/// print(updated); // (Earth, Jupiter, Mars, Venus)
171+
/// ```
165172
Iterable<E> followedBy(Iterable<E> other) {
166173
var self = this; // TODO(lrn): Remove when we can promote `this`.
167174
if (self is EfficientLengthIterable<E>) {
@@ -189,13 +196,24 @@ abstract class Iterable<E> {
189196
/// For example, [elementAt] may call `toElement` only once.
190197
///
191198
/// Equivalent to:
192-
/// ```dart
199+
/// ```
193200
/// Iterable<T> map<T>(T toElement(E e)) sync* {
194201
/// for (var value in this) {
195202
/// yield toElement(value);
196203
/// }
197204
/// }
198205
/// ```
206+
/// Example:
207+
/// ```dart import:convert
208+
/// var products = jsonDecode('''
209+
/// [
210+
/// {"name": "Screwdriver", "price": 42.00},
211+
/// {"name": "Wingnut", "price": 0.50}
212+
/// ]
213+
/// ''');
214+
/// var values = products.map((product) => product['price'] as double);
215+
/// var totalPrice = values.fold(0.0, (a, b) => a + b); // 42.5.
216+
/// ```
199217
Iterable<T> map<T>(T toElement(E e)) => MappedIterable<E, T>(this, toElement);
200218

201219
/// Returns a new lazy [Iterable] with all elements that satisfy the
@@ -210,6 +228,14 @@ abstract class Iterable<E> {
210228
/// Iterating will not cache results, and thus iterating multiple times over
211229
/// the returned [Iterable] may invoke the supplied
212230
/// function [test] multiple times on the same element.
231+
///
232+
/// Example:
233+
/// ```dart
234+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
235+
/// var result = numbers.where((x) => x < 5); // (1, 2, 3)
236+
/// result = numbers.where((x) => x > 5); // (6, 7)
237+
/// result = numbers.where((x) => x.isEven); // (2, 6)
238+
/// ```
213239
Iterable<E> where(bool test(E element)) => WhereIterable<E>(this, test);
214240

215241
/// Returns a new lazy [Iterable] with all elements that have type [T].
@@ -233,17 +259,18 @@ abstract class Iterable<E> {
233259
///
234260
/// Example:
235261
/// ```dart
236-
/// var pairs = [[1, 2], [3, 4]];
237-
/// var flattened = pairs.expand((pair) => pair).toList();
238-
/// print(flattened); // => [1, 2, 3, 4];
239-
///
240-
/// var input = [1, 2, 3];
241-
/// var duplicated = input.expand((i) => [i, i]).toList();
242-
/// print(duplicated); // => [1, 1, 2, 2, 3, 3]
262+
/// Iterable<int> count(int n) sync* {
263+
/// for (var i = 1; i <= n; i++) {
264+
/// yield i;
265+
/// }
266+
/// }
267+
///
268+
/// var numbers = [1, 3, 0, 2];
269+
/// print(numbers.expand(count)); // (1, 1, 2, 3, 1, 2)
243270
/// ```
244271
///
245272
/// Equivalent to:
246-
/// ```dart
273+
/// ```
247274
/// Iterable<T> expand<T>(Iterable<T> toElements(E e)) sync* {
248275
/// for (var value in this) {
249276
/// yield* toElements(value);
@@ -267,6 +294,15 @@ abstract class Iterable<E> {
267294
/// (see [Set.identity]) that its `contains` uses.
268295
/// Likewise the `Iterable` returned by a [Map.keys] call
269296
/// should use the same equality that the `Map` uses for keys.
297+
///
298+
/// Example:
299+
/// ```dart
300+
/// final gasPlanets = <int, String>{1: 'Jupiter', 2: 'Saturn'};
301+
/// final containsOne = gasPlanets.keys.contains(1); // true
302+
/// final containsFive = gasPlanets.keys.contains(5); // false
303+
/// final containsJupiter = gasPlanets.values.contains('Jupiter'); // true
304+
/// final containsMercury = gasPlanets.values.contains('Mercury'); // false
305+
/// ```
270306
bool contains(Object? element) {
271307
for (E e in this) {
272308
if (e == element) return true;
@@ -275,6 +311,16 @@ abstract class Iterable<E> {
275311
}
276312

277313
/// Invokes [action] on each element of this iterable in iteration order.
314+
///
315+
/// Example:
316+
/// ```dart
317+
/// final numbers = <int>[1, 2, 6, 7];
318+
/// numbers.forEach(print);
319+
/// // 1
320+
/// // 2
321+
/// // 6
322+
/// // 7
323+
/// ```
278324
void forEach(void action(E element)) {
279325
for (E element in this) action(element);
280326
}
@@ -288,7 +334,7 @@ abstract class Iterable<E> {
288334
/// Otherwise this method starts with the first element from the iterator,
289335
/// and then combines it with the remaining elements in iteration order,
290336
/// as if by:
291-
/// ```dart
337+
/// ```
292338
/// E value = iterable.first;
293339
/// iterable.skip(1).forEach((element) {
294340
/// value = combine(value, element);
@@ -297,7 +343,9 @@ abstract class Iterable<E> {
297343
/// ```
298344
/// Example of calculating the sum of an iterable:
299345
/// ```dart
300-
/// iterable.reduce((value, element) => value + element);
346+
/// final numbers = <double>[10, 2, 5, 0.5];
347+
/// final result = numbers.reduce((value, element) => value + element);
348+
/// print(result); // 17.5
301349
/// ```
302350
E reduce(E combine(E value, E element)) {
303351
Iterator<E> iterator = this.iterator;
@@ -317,7 +365,7 @@ abstract class Iterable<E> {
317365
/// Uses [initialValue] as the initial value,
318366
/// then iterates through the elements and updates the value with
319367
/// each element using the [combine] function, as if by:
320-
/// ```dart
368+
/// ```
321369
/// var value = initialValue;
322370
/// for (E element in this) {
323371
/// value = combine(value, element);
@@ -326,7 +374,11 @@ abstract class Iterable<E> {
326374
/// ```
327375
/// Example of calculating the sum of an iterable:
328376
/// ```dart
329-
/// iterable.fold(0, (prev, element) => prev + element);
377+
/// final numbers = <double>[10, 2, 5, 0.5];
378+
/// const initialValue = 100.0;
379+
/// final result = numbers.fold<double>(
380+
/// initialValue, (previousValue, element) => previousValue + element);
381+
/// print(result); // 117.5
330382
/// ```
331383
T fold<T>(T initialValue, T combine(T previousValue, E element)) {
332384
var value = initialValue;
@@ -338,6 +390,14 @@ abstract class Iterable<E> {
338390
///
339391
/// Checks every element in iteration order, and returns `false` if
340392
/// any of them make [test] return `false`, otherwise returns `true`.
393+
///
394+
/// Example:
395+
/// ```dart
396+
/// final planetsByMass = <double, String>{0.06: 'Mercury', 0.81: 'Venus',
397+
/// 0.11: 'Mars'};
398+
/// // Checks whether all keys are smaller than 1.
399+
/// final every = planetsByMass.keys.every((key) => key < 1.0); // true
400+
/// ```
341401
bool every(bool test(E element)) {
342402
for (E element in this) {
343403
if (!test(element)) return false;
@@ -351,6 +411,13 @@ abstract class Iterable<E> {
351411
/// converts each one to a [String] by calling [Object.toString],
352412
/// and then concatenates the strings, with the
353413
/// [separator] string interleaved between the elements.
414+
///
415+
/// Example:
416+
/// ```dart
417+
/// final planetsByMass = <double, String>{0.06: 'Mercury', 0.81: 'Venus',
418+
/// 0.11: 'Mars'};
419+
/// final joinedNames = planetsByMass.values.join('-'); // Mercury-Venus-Mars
420+
/// ```
354421
String join([String separator = ""]) {
355422
Iterator<E> iterator = this.iterator;
356423
if (!iterator.moveNext()) return "";
@@ -373,6 +440,13 @@ abstract class Iterable<E> {
373440
///
374441
/// Checks every element in iteration order, and returns `true` if
375442
/// any of them make [test] return `true`, otherwise returns false.
443+
///
444+
/// Example:
445+
/// ```dart
446+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
447+
/// var result = numbers.any((element) => element >= 5); // true;
448+
/// result = numbers.any((element) => element >= 10); // false;
449+
/// ```
376450
bool any(bool test(E element)) {
377451
for (E element in this) {
378452
if (test(element)) return true;
@@ -384,6 +458,14 @@ abstract class Iterable<E> {
384458
///
385459
/// The elements are in iteration order.
386460
/// The list is fixed-length if [growable] is false.
461+
///
462+
/// Example:
463+
/// ```dart
464+
/// final planets = <int, String>{1: 'Mercury', 2: 'Venus', 3: 'Mars'};
465+
/// final keysList = planets.keys.toList(growable: false); // [1, 2, 3]
466+
/// final valuesList =
467+
/// planets.values.toList(growable: false); // [Mercury, Venus, Mars]
468+
/// ```
387469
List<E> toList({bool growable = true}) {
388470
return List<E>.of(this, growable: growable);
389471
}
@@ -395,6 +477,12 @@ abstract class Iterable<E> {
395477
/// or it contains one or more elements that are equal.
396478
/// The order of the elements in the set is not guaranteed to be the same
397479
/// as for the iterable.
480+
///
481+
/// Example:
482+
/// ```dart
483+
/// final planets = <int, String>{1: 'Mercury', 2: 'Venus', 3: 'Mars'};
484+
/// final valueSet = planets.values.toSet(); // {Mercury, Venus, Mars}
485+
/// ```
398486
Set<E> toSet() => Set<E>.of(this);
399487

400488
/// Returns the number of elements in [this].
@@ -415,11 +503,25 @@ abstract class Iterable<E> {
415503
/// Whether this collection has no elements.
416504
///
417505
/// May be computed by checking if `iterator.moveNext()` returns `false`.
506+
///
507+
/// Example:
508+
/// ```dart
509+
/// final emptyList = <int>[];
510+
/// print(emptyList.isEmpty); // true;
511+
/// print(emptyList.iterator.moveNext()); // false
512+
/// ```
418513
bool get isEmpty => !iterator.moveNext();
419514

420515
/// Whether this collection has at least one element.
421516
///
422517
/// May be computed by checking if `iterator.moveNext()` returns `true`.
518+
///
519+
/// Example:
520+
/// ```dart
521+
/// final numbers = <int>{1, 2, 3};
522+
/// print(numbers.isNotEmpty); // true;
523+
/// print(numbers.iterator.moveNext()); // true
524+
/// ```
423525
bool get isNotEmpty => !isEmpty;
424526

425527
/// Returns a lazy iterable of the [count] first elements of this iterable.
@@ -431,6 +533,13 @@ abstract class Iterable<E> {
431533
/// elements have been seen.
432534
///
433535
/// The `count` must not be negative.
536+
///
537+
/// Example:
538+
/// ```dart
539+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
540+
/// final result = numbers.take(4); // (1, 2, 3, 5)
541+
/// final takeAll = numbers.take(100); // (1, 2, 3, 5, 6, 7)
542+
/// ```
434543
Iterable<E> take(int count) {
435544
return TakeIterable<E>(this, count);
436545
}
@@ -443,6 +552,15 @@ abstract class Iterable<E> {
443552
/// The elements can be computed by stepping through [iterator] until an
444553
/// element is found where `test(element)` is false. At that point,
445554
/// the returned iterable stops (its `moveNext()` returns false).
555+
///
556+
/// Example:
557+
/// ```dart
558+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
559+
/// var result = numbers.takeWhile((x) => x < 5); // (1, 2, 3)
560+
/// result = numbers.takeWhile((x) => x != 3); // (1, 2)
561+
/// result = numbers.takeWhile((x) => x != 4); // (1, 2, 3, 5, 6, 7)
562+
/// result = numbers.takeWhile((x) => x.isOdd); // (1)
563+
/// ```
446564
Iterable<E> takeWhile(bool test(E value)) {
447565
return TakeWhileIterable<E>(this, test);
448566
}
@@ -460,6 +578,13 @@ abstract class Iterable<E> {
460578
/// through earlier elements, for example when iterating a [List].
461579
/// Such iterables are allowed to ignore the initial skipped elements.
462580
///
581+
/// Example:
582+
/// ```dart
583+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
584+
/// final result = numbers.skip(4); // (6, 7)
585+
/// final skipAll = numbers.skip(100); // () - no elements.
586+
/// ```
587+
///
463588
/// The [count] must not be negative.
464589
Iterable<E> skip(int count) {
465590
return SkipIterable<E>(this, count);
@@ -475,6 +600,15 @@ abstract class Iterable<E> {
475600
/// true. If all elements satisfy `test` the resulting iterable is empty,
476601
/// otherwise it iterates the remaining elements in their original order,
477602
/// starting with the first element for which `test(element)` returns `false`.
603+
///
604+
/// Example:
605+
/// ```dart
606+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
607+
/// var result = numbers.skipWhile((x) => x < 5); // (5, 6, 7)
608+
/// result = numbers.skipWhile((x) => x != 3); // (3, 5, 6, 7)
609+
/// result = numbers.skipWhile((x) => x != 4); // ()
610+
/// result = numbers.skipWhile((x) => x.isOdd); // (2, 3, 5, 6, 7)
611+
/// ```
478612
Iterable<E> skipWhile(bool test(E value)) {
479613
return SkipWhileIterable<E>(this, test);
480614
}
@@ -527,6 +661,15 @@ abstract class Iterable<E> {
527661
///
528662
/// Iterates through elements and returns the first to satisfy [test].
529663
///
664+
/// Example:
665+
/// ```dart
666+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
667+
/// var result = numbers.firstWhere((element) => element < 5); // 1
668+
/// result = numbers.firstWhere((element) => element > 5); // 6
669+
/// result =
670+
/// numbers.firstWhere((element) => element > 10, orElse: () => -1); // -1
671+
/// ```
672+
///
530673
/// If no element satisfies [test], the result of invoking the [orElse]
531674
/// function is returned.
532675
/// If [orElse] is omitted, it defaults to throwing a [StateError].
@@ -547,6 +690,15 @@ abstract class Iterable<E> {
547690
/// checks `test(element)` for each,
548691
/// and finally returns that last one that matched.
549692
///
693+
/// Example:
694+
/// ```dart
695+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
696+
/// var result = numbers.lastWhere((element) => element < 5); // 3
697+
/// result = numbers.lastWhere((element) => element > 5); // 7
698+
/// result = numbers.lastWhere((element) => element > 10,
699+
/// orElse: () => -1); // -1
700+
/// ```
701+
///
550702
/// If no element satisfies [test], the result of invoking the [orElse]
551703
/// function is returned.
552704
/// If [orElse] is omitted, it defaults to throwing a [StateError].
@@ -571,6 +723,22 @@ abstract class Iterable<E> {
571723
/// If more than one matching element is found, throws [StateError].
572724
/// If no matching element is found, returns the result of [orElse].
573725
/// If [orElse] is omitted, it defaults to throwing a [StateError].
726+
///
727+
/// Example:
728+
/// ```dart
729+
/// final numbers = <int>[2, 2, 10];
730+
/// var result = numbers.singleWhere((element) => element > 5); // 10
731+
/// ```
732+
/// When no matching element is found, the result of calling [orElse] is
733+
/// returned instead.
734+
/// ```dart continued
735+
/// result = numbers.singleWhere((element) => element == 1,
736+
/// orElse: () => -1); // -1
737+
/// ```
738+
/// There must not be more than one matching element.
739+
/// ```dart continued
740+
/// result = numbers.singleWhere((element) => element == 2); // Throws Error.
741+
/// ```
574742
E singleWhere(bool test(E element), {E orElse()?}) {
575743
late E result;
576744
bool foundMatching = false;
@@ -597,6 +765,12 @@ abstract class Iterable<E> {
597765
/// May iterate through the elements in iteration order, ignoring the
598766
/// first [index] elements and then returning the next.
599767
/// Some iterables may have a more efficient way to find the element.
768+
///
769+
/// Example:
770+
/// ```dart
771+
/// final numbers = <int>[1, 2, 3, 5, 6, 7];
772+
/// final elementAt = numbers.elementAt(4); // 6
773+
/// ```
600774
E elementAt(int index) {
601775
RangeError.checkNotNegative(index, "index");
602776
int elementIndex = 0;

0 commit comments

Comments
 (0)