| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * The [Iterable] interface allows to get an [Iterator] out of an | 6 * The [Iterable] interface allows to get an [Iterator] out of an |
| 7 * [Iterable] object. | 7 * [Iterable] object. |
| 8 * | 8 * |
| 9 * This interface is used by the for-in construct to iterate over an | 9 * This interface is used by the for-in construct to iterate over an |
| 10 * [Iterable] object. | 10 * [Iterable] object. |
| 11 * The for-in construct takes an [Iterable] object at the right-hand | 11 * The for-in construct takes an [Iterable] object at the right-hand |
| 12 * side, and calls its [iterator] method to get an [Iterator] on it. | 12 * side, and calls its [iterator] method to get an [Iterator] on it. |
| 13 * | 13 * |
| 14 * A user-defined class that implements the [Iterable] interface can | 14 * A user-defined class that implements the [Iterable] interface can |
| 15 * be used as the right-hand side of a for-in construct. | 15 * be used as the right-hand side of a for-in construct. |
| 16 */ | 16 */ |
| 17 abstract class Iterable<E> { | 17 abstract class Iterable<E> { |
| 18 const Iterable(); | 18 const Iterable(); |
| 19 | 19 |
| 20 /** | 20 /** |
| 21 * Returns an [Iterator] that iterates over this [Iterable] object. | 21 * Returns an [Iterator] that iterates over this [Iterable] object. |
| 22 */ | 22 */ |
| 23 Iterator<E> get iterator; | 23 Iterator<E> get iterator; |
| 24 | 24 |
| 25 /** | 25 /** |
| 26 * Returns a new collection with the elements [: f(e) :] | 26 * Returns a lazy [Iterable] where each element [:e:] of [this] is replaced |
| 27 * for each element [:e:] of this collection. | 27 * by the result of [:f(e):]. |
| 28 * | 28 * |
| 29 * Subclasses of [Collection] should implement the [mappedBy] method | 29 * This method returns a view of the mapped elements. As long as the |
| 30 * to return a collection of the same general type as themselves. | 30 * returned [Iterable] is not iterated over, the supplied function [f] will |
| 31 * E.g., [List.mappedBy] should return a [List]. | 31 * not be invoked. The transformed elements will not be cached. Iterating |
| 32 * multiple times over the the returned [Iterable] will invoke the supplied |
| 33 * function [f] multiple times on the same element. |
| 32 */ | 34 */ |
| 33 Collection mappedBy(f(E element)) { | 35 Iterable mappedBy(f(E element)) => new MappedIterable<E, dynamic>(this, f); |
| 34 // TODO(floitsch): this is just a temporary function to provide a complete | |
| 35 // skeleton. It will be changed to become lazy soon. | |
| 36 List result = []; | |
| 37 for (E element in this) result.add(f(element)); | |
| 38 return result; | |
| 39 } | |
| 40 | 36 |
| 41 /** | 37 /** |
| 42 * Returns a collection with the elements of this collection | 38 * Returns a collection with the elements of this collection |
| 43 * that satisfy the predicate [f]. | 39 * that satisfy the predicate [f]. |
| 44 * | 40 * |
| 45 * The returned collection should be of the same type as the collection | 41 * The returned collection should be of the same type as the collection |
| 46 * creating it. | 42 * creating it. |
| 47 * | 43 * |
| 48 * An element satisfies the predicate [f] if [:f(element):] | 44 * An element satisfies the predicate [f] if [:f(element):] |
| 49 * returns true. | 45 * returns true. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 count++; | 124 count++; |
| 129 } | 125 } |
| 130 return count; | 126 return count; |
| 131 } | 127 } |
| 132 | 128 |
| 133 /** | 129 /** |
| 134 * Returns true if there is no element in this collection. | 130 * Returns true if there is no element in this collection. |
| 135 */ | 131 */ |
| 136 bool get isEmpty => !iterator.moveNext(); | 132 bool get isEmpty => !iterator.moveNext(); |
| 137 } | 133 } |
| 134 |
| 135 class MappedIterable<S, T> extends Iterable<T> { |
| 136 final Iterable<S> _iterable; |
| 137 final Function _f; |
| 138 |
| 139 MappedIterable(this._iterable, T this._f(S element)); |
| 140 |
| 141 Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f); |
| 142 } |
| 143 |
| 144 class MappedIterator<S, T> extends Iterator<T> { |
| 145 T _current; |
| 146 Iterator<S> _iterator; |
| 147 Function _f; |
| 148 |
| 149 MappedIterator(this._iterator, T this._f(S element)); |
| 150 |
| 151 bool moveNext() { |
| 152 if (_iterator.moveNext()) { |
| 153 _current = _f(_iterator.current); |
| 154 return true; |
| 155 } else { |
| 156 _current = null; |
| 157 return false; |
| 158 } |
| 159 } |
| 160 |
| 161 T get current => _current; |
| 162 } |
| 163 |
| 164 class FilteredIterable<E> extends Iterable<E> { |
| 165 final Iterable<E> _iterable; |
| 166 final Function _f; |
| 167 |
| 168 FilteredIterable(this._iterable, bool this._f(E element)); |
| 169 |
| 170 Iterator<E> get iterator => new FilteredIterator<E>(_iterable.iterator, _f); |
| 171 } |
| 172 |
| 173 class FilteredIterator<E> extends Iterator<E> { |
| 174 E _current; |
| 175 Iterator _iterator; |
| 176 Function _f; |
| 177 |
| 178 FilteredIterator(this._iterator, bool this._f(E element)); |
| 179 |
| 180 bool moveNext() { |
| 181 while (_iterator.moveNext()) { |
| 182 if (_f(_iterator.current)) { |
| 183 _current = _iterator.current; |
| 184 return true; |
| 185 } |
| 186 } |
| 187 _current = null; |
| 188 return false; |
| 189 } |
| 190 |
| 191 E get current => _current; |
| 192 } |
| OLD | NEW |