blob: 9a0a674af8ab2a59ea55c4346fa2e3bc99a78bfa [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart.collection;
/// This [Iterable] mixin implements all [Iterable] members except `iterator`.
///
/// All other methods are implemented in terms of `iterator`.
// @Deprecated("Use Iterable instead")
typedef IterableMixin<E> = Iterable<E>;
/// Base class for implementing [Iterable].
///
/// This class implements all methods of [Iterable], except [Iterable.iterator],
/// in terms of `iterator`.
// @Deprecated("Use Iterable instead")
typedef IterableBase<E> = Iterable<E>;
/// Operations on iterables with nullable elements.
@Since("3.0")
extension NullableIterableExtensions<T extends Object> on Iterable<T?> {
/// The non-`null` elements of this iterable.
///
/// The same elements as this iterable, except that `null` values
/// are omitted.
Iterable<T> get nonNulls => NonNullsIterable<T>(this);
}
/// Operations on iterables.
@Since("3.0")
extension IterableExtensions<T> on Iterable<T> {
/// Pairs of elements of the indices and elements of this iterable.
///
/// The elements are `(0, this.first)` through
/// `(this.length - 1, this.last)`, in index/iteration order.
@pragma('vm:prefer-inline')
Iterable<(int, T)> get indexed => IndexedIterable<T>(this, 0);
/// The first element of this iterator, or `null` if the iterable is empty.
T? get firstOrNull {
var iterator = this.iterator;
if (iterator.moveNext()) return iterator.current;
return null;
}
/// The last element of this iterable, or `null` if the iterable is empty.
///
/// This computation may not be efficient.
/// The last value is potentially found by iterating the entire iterable
/// and temporarily storing every value.
/// The process only iterates the iterable once.
/// If iterating more than once is not a problem, it may be more efficient
/// for some iterables to do:
/// ```dart
/// var lastOrNull = iterable.isEmpty ? null : iterable.last;
/// ```
T? get lastOrNull {
if (this is EfficientLengthIterable) {
if (isEmpty) return null;
return last;
}
var iterator = this.iterator;
if (!iterator.moveNext()) return null;
T result;
do {
result = iterator.current;
} while (iterator.moveNext());
return result;
}
/// The single element of this iterator, or `null`.
///
/// If the iterator has precisely one element, this is that element.
/// Otherwise, if the iterator has zero elements, or it has two or more,
/// the value is `null`.
T? get singleOrNull {
var iterator = this.iterator;
if (iterator.moveNext()) {
var result = iterator.current;
if (!iterator.moveNext()) return result;
}
return null;
}
/// The element at position [index] of this iterable, or `null`.
///
/// The [index] is zero based, and must be non-negative.
///
/// Returns the result of `elementAt(index)` if the iterable has
/// at least `index + 1` elements, and `null` otherwise.
T? elementAtOrNull(int index) {
RangeError.checkNotNegative(index, "index");
if (this is EfficientLengthIterable) {
if (index >= length) return null;
return elementAt(index);
}
var iterator = this.iterator;
do {
if (!iterator.moveNext()) return null;
} while (--index >= 0);
return iterator.current;
}
}