Chromium Code Reviews| Index: sdk/lib/core/iterable.dart |
| diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart |
| index b7942887cbd2ca74c4b8d5ac284732ae8a38bc8a..06c8efa8b5f657b35e99ea0d8cc5fe306e986594 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(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<E> extends Iterable<E> { |
|
Lasse Reichstein Nielsen
2012/11/20 14:11:47
Make it <S, T> (S: source type, T target type) eve
floitsch
2012/11/20 16:41:26
Done.
|
| + final Iterable _iterable; |
| + final Function _f; |
| + |
| + MappedIterable(this._iterable, E this._f(element)); |
|
Anders Johnsen
2012/11/20 06:29:15
this._f(E element) as type
floitsch
2012/11/20 13:33:44
No. The type is E f(element). We don't know that t
Anders Johnsen
2012/11/20 13:39:46
Got you, it's the other return iterator type.
|
| + |
| + Iterator<E> get iterator => new MappedIterator<E>(_iterable.iterator, _f); |
| +} |
| + |
| +class MappedIterator<E> extends Iterator<E> { |
|
Anders Johnsen
2012/11/20 06:29:15
Are you sure we want these to be public? At least
floitsch
2012/11/20 13:33:44
They will be in the library that is shared between
|
| + E _current; |
| + Iterator _iterator; |
| + Function _f; |
| + |
| + MappedIterator(this._iterator, E this._f(element)); |
| + |
| + bool moveNext() { |
| + if (_iterator.moveNext()) { |
| + _current = _f(_iterator.current); |
| + return true; |
| + } else { |
| + _current = null; |
| + return false; |
| + } |
| + } |
| + |
| + E 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; |
| +} |