| Index: sdk/lib/core/iterable.dart
|
| diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
|
| index b7942887cbd2ca74c4b8d5ac284732ae8a38bc8a..b753756802dfe34e2bc70290374b134097d5911d 100644
|
| --- a/sdk/lib/core/iterable.dart
|
| +++ b/sdk/lib/core/iterable.dart
|
| @@ -23,20 +23,16 @@ abstract class Iterable<E> {
|
| Iterator<E> get iterator;
|
|
|
| /**
|
| - * Returns a new collection with the elements [: f(e) :]
|
| - * for each element [:e:] of this collection.
|
| + * Returns a lazy [Iterable] where each element [:e:] of [this] is replaced
|
| + * by the result of [:f(e):].
|
| *
|
| - * Subclasses of [Collection] should implement the [mappedBy] method
|
| - * to return a collection of the same general type as themselves.
|
| - * E.g., [List.mappedBy] should return a [List].
|
| + * This method returns a view of the mapped elements. As long as the
|
| + * returned [Iterable] is not iterated over, the supplied function [f] will
|
| + * not be invoked. The transformed elements will not be cached. Iterating
|
| + * multiple times over the the returned [Iterable] will invoke the supplied
|
| + * function [f] multiple times on the same element.
|
| */
|
| - Collection mappedBy(f(E element)) {
|
| - // TODO(floitsch): this is just a temporary function to provide a complete
|
| - // skeleton. It will be changed to become lazy soon.
|
| - List result = [];
|
| - for (E element in this) result.add(f(element));
|
| - return result;
|
| - }
|
| + Iterable mappedBy(f(E element)) => new MappedIterable<E, dynamic>(this, f);
|
|
|
| /**
|
| * Returns a collection with the elements of this collection
|
| @@ -135,3 +131,62 @@ abstract class Iterable<E> {
|
| */
|
| bool get isEmpty => !iterator.moveNext();
|
| }
|
| +
|
| +class MappedIterable<S, T> extends Iterable<T> {
|
| + final Iterable<S> _iterable;
|
| + final Function _f;
|
| +
|
| + MappedIterable(this._iterable, T this._f(S element));
|
| +
|
| + Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f);
|
| +}
|
| +
|
| +class MappedIterator<S, T> extends Iterator<T> {
|
| + T _current;
|
| + Iterator<S> _iterator;
|
| + Function _f;
|
| +
|
| + MappedIterator(this._iterator, T this._f(S element));
|
| +
|
| + bool moveNext() {
|
| + if (_iterator.moveNext()) {
|
| + _current = _f(_iterator.current);
|
| + return true;
|
| + } else {
|
| + _current = null;
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + T get current => _current;
|
| +}
|
| +
|
| +class FilteredIterable<E> extends Iterable<E> {
|
| + final Iterable<E> _iterable;
|
| + final Function _f;
|
| +
|
| + FilteredIterable(this._iterable, bool this._f(E element));
|
| +
|
| + Iterator<E> get iterator => new FilteredIterator<E>(_iterable.iterator, _f);
|
| +}
|
| +
|
| +class FilteredIterator<E> extends Iterator<E> {
|
| + E _current;
|
| + Iterator _iterator;
|
| + Function _f;
|
| +
|
| + FilteredIterator(this._iterator, bool this._f(E element));
|
| +
|
| + bool moveNext() {
|
| + while (_iterator.moveNext()) {
|
| + if (_f(_iterator.current)) {
|
| + _current = _iterator.current;
|
| + return true;
|
| + }
|
| + }
|
| + _current = null;
|
| + return false;
|
| + }
|
| +
|
| + E get current => _current;
|
| +}
|
|
|