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

Side by Side Diff: sdk/lib/collection/iterable.dart

Issue 14022007: Move Iterable implementation to collection. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 part of dart.collection;
6
7 /**
8 * This [Iterable] mixin implements all [Iterable] members except `iterator`.
9 *
10 * All other methods are implemented in terms of `iterator`.
11 */
12 abstract class IterableMixin<E> implements Iterable<E> {
13 Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
14
15 Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
16
17 Iterable expand(Iterable f(E element)) =>
18 new ExpandIterable<E, dynamic>(this, f);
19
20 bool contains(E element) {
21 for (E e in this) {
22 if (e == element) return true;
23 }
24 return false;
25 }
26
27 void forEach(void f(E element)) {
28 for (E element in this) f(element);
29 }
30
31 E reduce(E combine(E value, E element)) {
32 Iterator<E> iterator = this.iterator;
33 if (!iterator.moveNext()) {
34 throw new StateError("No elements");
35 }
36 E value = iterator.current;
37 while (iterator.moveNext()) {
38 value = combine(value, iterator.current);
39 }
40 return value;
41 }
42
43 dynamic fold(var initialValue,
44 dynamic combine(var previousValue, E element)) {
45 var value = initialValue;
46 for (E element in this) value = combine(value, element);
47 return value;
48 }
49
50 bool every(bool f(E element)) {
51 for (E element in this) {
52 if (!f(element)) return false;
53 }
54 return true;
55 }
56
57 String join([String separator]) {
58 Iterator<E> iterator = this.iterator;
59 if (!iterator.moveNext()) return "";
60 StringBuffer buffer = new StringBuffer();
61 if (separator == null || separator == "") {
62 do {
63 buffer.write("${iterator.current}");
64 } while (iterator.moveNext());
65 } else {
66 buffer.write("${iterator.current}");
67 while (iterator.moveNext()) {
68 buffer.write(separator);
69 buffer.write("${iterator.current}");
70 }
71 }
72 return buffer.toString();
73 }
74
75 bool any(bool f(E element)) {
76 for (E element in this) {
77 if (f(element)) return true;
78 }
79 return false;
80 }
81
82 List<E> toList({ bool growable: true }) =>
83 new List<E>.from(this, growable: growable);
84
85 Set<E> toSet() => new Set<E>.from(this);
86
87 int get length {
88 int count = 0;
89 Iterator it = iterator;
90 while (it.moveNext()) {
91 count++;
92 }
93 return count;
94 }
95
96 bool get isEmpty => !iterator.moveNext();
97
98 Iterable<E> take(int n) {
99 return new TakeIterable<E>(this, n);
100 }
101
102 Iterable<E> takeWhile(bool test(E value)) {
103 return new TakeWhileIterable<E>(this, test);
104 }
105
106 Iterable<E> skip(int n) {
107 return new SkipIterable<E>(this, n);
108 }
109
110 Iterable<E> skipWhile(bool test(E value)) {
111 return new SkipWhileIterable<E>(this, test);
112 }
113
114 E get first {
115 Iterator it = iterator;
116 if (!it.moveNext()) {
117 throw new StateError("No elements");
118 }
119 return it.current;
120 }
121
122 E get last {
123 Iterator it = iterator;
124 if (!it.moveNext()) {
125 throw new StateError("No elements");
126 }
127 E result;
128 do {
129 result = it.current;
130 } while(it.moveNext());
131 return result;
132 }
133
134 E get single {
135 Iterator it = iterator;
136 if (!it.moveNext()) throw new StateError("No elements");
137 E result = it.current;
138 if (it.moveNext()) throw new StateError("More than one element");
139 return result;
140 }
141
142 E firstWhere(bool test(E value), { E orElse() }) {
143 // TODO(floitsch): check that arguments are of correct type?
144 for (E element in this) {
145 if (test(element)) return element;
146 }
147 if (orElse != null) return orElse();
148 throw new StateError("No matching element");
149 }
150
151 E lastWhere(bool test(E value), {E orElse()}) {
152 // TODO(floitsch): check that arguments are of correct type?
153 E result = null;
154 bool foundMatching = false;
155 for (E element in this) {
156 if (test(element)) {
157 result = element;
158 foundMatching = true;
159 }
160 }
161 if (foundMatching) return result;
162 if (orElse != null) return orElse();
163 throw new StateError("No matching element");
164 }
165
166 E singleWhere(bool test(E value)) {
167 // TODO(floitsch): check that argument is of correct type?
168 E result = null;
169 bool foundMatching = false;
170 for (E element in this) {
171 if (test(element)) {
172 if (foundMatching) {
173 throw new StateError("More than one matching element");
174 }
175 result = element;
176 foundMatching = true;
177 }
178 }
179 if (foundMatching) return result;
180 throw new StateError("No matching element");
181 }
182
183 E elementAt(int index) {
184 if (index is! int || index < 0) throw new RangeError.value(index);
185 int remaining = index;
186 for (E element in this) {
187 if (remaining == 0) return element;
188 remaining--;
189 }
190 throw new RangeError.value(index);
191 }
192 }
193
194 /**
195 * Base class for implementing [Iterable].
196 *
197 * This class implements all methods of [Iterable] except [Iterable.iterator]
198 * in terms of `iterator`.
199 */
200 abstract class IterableBase<E> implements Iterable<E> {
201 // TODO(lrn): Base this on IterableMixin if there ever becomes a way
202 // to combine const constructors and mixins.
203 const IterableBase();
204
205 Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
206
207 Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
208
209 Iterable expand(Iterable f(E element)) =>
210 new ExpandIterable<E, dynamic>(this, f);
211
212 bool contains(E element) {
213 for (E e in this) {
214 if (e == element) return true;
215 }
216 return false;
217 }
218
219 void forEach(void f(E element)) {
220 for (E element in this) f(element);
221 }
222
223 E reduce(E combine(E value, E element)) {
224 Iterator<E> iterator = this.iterator;
225 if (!iterator.moveNext()) {
226 throw new StateError("No elements");
227 }
228 E value = iterator.current;
229 while (iterator.moveNext()) {
230 value = combine(value, iterator.current);
231 }
232 return value;
233 }
234
235 dynamic fold(var initialValue,
236 dynamic combine(var previousValue, E element)) {
237 var value = initialValue;
238 for (E element in this) value = combine(value, element);
239 return value;
240 }
241
242 bool every(bool f(E element)) {
243 for (E element in this) {
244 if (!f(element)) return false;
245 }
246 return true;
247 }
248
249 String join([String separator]) {
250 Iterator<E> iterator = this.iterator;
251 if (!iterator.moveNext()) return "";
252 StringBuffer buffer = new StringBuffer();
253 if (separator == null || separator == "") {
254 do {
255 buffer.write("${iterator.current}");
256 } while (iterator.moveNext());
257 } else {
258 buffer.write("${iterator.current}");
259 while (iterator.moveNext()) {
260 buffer.write(separator);
261 buffer.write("${iterator.current}");
262 }
263 }
264 return buffer.toString();
265 }
266
267 bool any(bool f(E element)) {
268 for (E element in this) {
269 if (f(element)) return true;
270 }
271 return false;
272 }
273
274 List<E> toList({ bool growable: true }) =>
275 new List<E>.from(this, growable: growable);
276
277 Set<E> toSet() => new Set<E>.from(this);
278
279 int get length {
280 int count = 0;
281 Iterator it = iterator;
282 while (it.moveNext()) {
283 count++;
284 }
285 return count;
286 }
287
288 bool get isEmpty => !iterator.moveNext();
289
290 Iterable<E> take(int n) {
291 return new TakeIterable<E>(this, n);
292 }
293
294 Iterable<E> takeWhile(bool test(E value)) {
295 return new TakeWhileIterable<E>(this, test);
296 }
297
298 Iterable<E> skip(int n) {
299 return new SkipIterable<E>(this, n);
300 }
301
302 Iterable<E> skipWhile(bool test(E value)) {
303 return new SkipWhileIterable<E>(this, test);
304 }
305
306 E get first {
307 Iterator it = iterator;
308 if (!it.moveNext()) {
309 throw new StateError("No elements");
310 }
311 return it.current;
312 }
313
314 E get last {
315 Iterator it = iterator;
316 if (!it.moveNext()) {
317 throw new StateError("No elements");
318 }
319 E result;
320 do {
321 result = it.current;
322 } while(it.moveNext());
323 return result;
324 }
325
326 E get single {
327 Iterator it = iterator;
328 if (!it.moveNext()) throw new StateError("No elements");
329 E result = it.current;
330 if (it.moveNext()) throw new StateError("More than one element");
331 return result;
332 }
333
334 E firstWhere(bool test(E value), { E orElse() }) {
335 // TODO(floitsch): check that arguments are of correct type?
336 for (E element in this) {
337 if (test(element)) return element;
338 }
339 if (orElse != null) return orElse();
340 throw new StateError("No matching element");
341 }
342
343 E lastWhere(bool test(E value), {E orElse()}) {
344 // TODO(floitsch): check that arguments are of correct type?
345 E result = null;
346 bool foundMatching = false;
347 for (E element in this) {
348 if (test(element)) {
349 result = element;
350 foundMatching = true;
351 }
352 }
353 if (foundMatching) return result;
354 if (orElse != null) return orElse();
355 throw new StateError("No matching element");
356 }
357
358 E singleWhere(bool test(E value)) {
359 // TODO(floitsch): check that argument is of correct type?
360 E result = null;
361 bool foundMatching = false;
362 for (E element in this) {
363 if (test(element)) {
364 if (foundMatching) {
365 throw new StateError("More than one matching element");
366 }
367 result = element;
368 foundMatching = true;
369 }
370 }
371 if (foundMatching) return result;
372 throw new StateError("No matching element");
373 }
374
375 E elementAt(int index) {
376 if (index is! int || index < 0) throw new RangeError.value(index);
377 int remaining = index;
378 for (E element in this) {
379 if (remaining == 0) return element;
380 remaining--;
381 }
382 throw new RangeError.value(index);
383 }
384 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698