Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1114)

Unified Diff: sdk/lib/core/iterable.dart

Issue 11414069: Make mappedBy lazy. (Closed) Base URL: https://dart.googlecode.com/svn/experimental/lib_v2/dart
Patch Set: Remove CollectionUtils.mappedBy in Swarm. Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
+}

Powered by Google App Engine
This is Rietveld 408576698