OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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 part of dart.collection; | 5 part of dart.collection; |
6 | 6 |
7 /** | 7 /** |
8 * This class provides default implementations for Iterables (including Lists). | 8 * This class provides default implementations for Iterables (including Lists). |
9 * | 9 * |
10 * Once Dart receives Mixins it will be replaced with mixin classes. | 10 * Once Dart receives Mixins it will be replaced with mixin classes. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 static dynamic fold(Iterable iterable, | 52 static dynamic fold(Iterable iterable, |
53 dynamic initialValue, | 53 dynamic initialValue, |
54 dynamic combine(dynamic previousValue, element)) { | 54 dynamic combine(dynamic previousValue, element)) { |
55 for (final element in iterable) { | 55 for (final element in iterable) { |
56 initialValue = combine(initialValue, element); | 56 initialValue = combine(initialValue, element); |
57 } | 57 } |
58 return initialValue; | 58 return initialValue; |
59 } | 59 } |
60 | 60 |
61 /** | 61 /** |
62 * Simple implementation for [Collection.removeAll]. | |
63 * | |
64 * This implementation assumes that [Collection.remove] on [collection] | |
65 * is efficient. The [:remove:] method on [List] objects is typically | |
66 * not efficient since it requires linear search to find an element. | |
67 */ | |
68 static void removeAll(Collection collection, Iterable elementsToRemove) { | |
69 for (Object object in elementsToRemove) { | |
70 collection.remove(object); | |
71 } | |
72 } | |
73 | |
74 /** | |
75 * Implementation of [Collection.removeAll] for lists. | |
76 * | |
77 * This implementation assumes that [Collection.remove] is not efficient | |
78 * (as it usually isn't on a [List]) and uses [Collection.removeMathcing] | |
79 * instead of just repeatedly calling remove. | |
80 */ | |
81 static void removeAllList(Collection collection, Iterable elementsToRemove) { | |
82 Set setToRemove; | |
83 // Assume [contains] is efficient on a Set. | |
84 if (elementsToRemove is Set) { | |
85 setToRemove = elementsToRemove; | |
86 } else { | |
87 setToRemove = elementsToRemove.toSet(); | |
88 } | |
89 collection.removeWhere(setToRemove.contains); | |
90 } | |
91 | |
92 /** | |
93 * Simple implemenation for [Collection.retainAll]. | |
94 * | |
95 * This implementation assumes that [Collecton.retainWhere] on [collection] | |
96 * is efficient. | |
97 */ | |
98 static void retainAll(Collection collection, Iterable elementsToRetain) { | |
99 Set lookup; | |
100 if (elementsToRetain is Set) { | |
101 lookup = elementsToRetain; | |
102 } else { | |
103 lookup = elementsToRetain.toSet(); | |
104 } | |
105 if (lookup.isEmpty) { | |
106 collection.clear(); | |
107 return; | |
108 } | |
109 collection.retainWhere(lookup.contains); | |
110 } | |
111 | |
112 /** | |
113 * Simple implemenation for [Collection.removeWhere]. | |
114 * | |
115 * This implementation assumes that [Collecton.removeAll] on [collection] is | |
116 * efficient. | |
117 */ | |
118 static void removeWhere(Collection collection, bool test(var element)) { | |
119 List elementsToRemove = []; | |
120 for (var element in collection) { | |
121 if (test(element)) elementsToRemove.add(element); | |
122 } | |
123 collection.removeAll(elementsToRemove); | |
124 } | |
125 | |
126 /** | |
127 * Removes elements matching [test] from [list]. | 62 * Removes elements matching [test] from [list]. |
128 * | 63 * |
129 * This is performed in two steps, to avoid exposing an inconsistent state | 64 * This is performed in two steps, to avoid exposing an inconsistent state |
130 * to the [test] function. First the elements to retain are found, and then | 65 * to the [test] function. First the elements to retain are found, and then |
131 * the original list is updated to contain those elements. | 66 * the original list is updated to contain those elements. |
132 */ | 67 */ |
133 static void removeWhereList(List list, bool test(var element)) { | 68 static void removeWhereList(List list, bool test(var element)) { |
134 List retained = []; | 69 List retained = []; |
135 int length = list.length; | 70 int length = list.length; |
136 for (int i = 0; i < length; i++) { | 71 for (int i = 0; i < length; i++) { |
137 var element = list[i]; | 72 var element = list[i]; |
138 if (!test(element)) { | 73 if (!test(element)) { |
139 retained.add(element); | 74 retained.add(element); |
140 } | 75 } |
141 if (length != list.length) { | 76 if (length != list.length) { |
142 throw new ConcurrentModificationError(list); | 77 throw new ConcurrentModificationError(list); |
143 } | 78 } |
144 } | 79 } |
145 if (retained.length == length) return; | 80 if (retained.length == length) return; |
146 list.length = retained.length; | 81 list.length = retained.length; |
147 for (int i = 0; i < retained.length; i++) { | 82 for (int i = 0; i < retained.length; i++) { |
148 list[i] = retained[i]; | 83 list[i] = retained[i]; |
149 } | 84 } |
150 } | 85 } |
151 | 86 |
152 /** | |
153 * Simple implemenation for [Collection.retainWhere]. | |
154 * | |
155 * This implementation assumes that [Collecton.removeAll] on [collection] is | |
156 * efficient. | |
157 */ | |
158 static void retainWhere(Collection collection, bool test(var element)) { | |
159 List elementsToRemove = []; | |
160 for (var element in collection) { | |
161 if (!test(element)) elementsToRemove.add(element); | |
162 } | |
163 collection.removeAll(elementsToRemove); | |
164 } | |
165 | |
166 static bool isEmpty(Iterable iterable) { | 87 static bool isEmpty(Iterable iterable) { |
167 return !iterable.iterator.moveNext(); | 88 return !iterable.iterator.moveNext(); |
168 } | 89 } |
169 | 90 |
170 static dynamic first(Iterable iterable) { | 91 static dynamic first(Iterable iterable) { |
171 Iterator it = iterable.iterator; | 92 Iterator it = iterable.iterator; |
172 if (!it.moveNext()) { | 93 if (!it.moveNext()) { |
173 throw new StateError("No elements"); | 94 throw new StateError("No elements"); |
174 } | 95 } |
175 return it.current; | 96 return it.current; |
176 } | 97 } |
177 | 98 |
178 static dynamic last(Iterable iterable) { | 99 static dynamic last(Iterable iterable) { |
179 Iterator it = iterable.iterator; | 100 Iterator it = iterable.iterator; |
180 if (!it.moveNext()) { | 101 if (!it.moveNext()) { |
181 throw new StateError("No elements"); | 102 throw new StateError("No elements"); |
182 } | 103 } |
183 dynamic result; | 104 dynamic result; |
184 do { | 105 do { |
185 result = it.current; | 106 result = it.current; |
186 } while(it.moveNext()); | 107 } while(it.moveNext()); |
187 return result; | 108 return result; |
188 } | 109 } |
189 | 110 |
190 static dynamic min(Iterable iterable, [int compare(var a, var b)]) { | |
191 if (compare == null) compare = Comparable.compare; | |
192 Iterator it = iterable.iterator; | |
193 if (!it.moveNext()) { | |
194 return null; | |
195 } | |
196 var min = it.current; | |
197 while (it.moveNext()) { | |
198 if (compare(min, it.current) > 0) min = it.current; | |
199 } | |
200 return min; | |
201 } | |
202 | |
203 static dynamic max(Iterable iterable, [int compare(var a, var b)]) { | |
204 if (compare == null) compare = Comparable.compare; | |
205 Iterator it = iterable.iterator; | |
206 if (!it.moveNext()) { | |
207 return null; | |
208 } | |
209 var max = it.current; | |
210 while (it.moveNext()) { | |
211 if (compare(max, it.current) < 0) max = it.current; | |
212 } | |
213 return max; | |
214 } | |
215 | |
216 static dynamic single(Iterable iterable) { | 111 static dynamic single(Iterable iterable) { |
217 Iterator it = iterable.iterator; | 112 Iterator it = iterable.iterator; |
218 if (!it.moveNext()) throw new StateError("No elements"); | 113 if (!it.moveNext()) throw new StateError("No elements"); |
219 dynamic result = it.current; | 114 dynamic result = it.current; |
220 if (it.moveNext()) throw new StateError("More than one element"); | 115 if (it.moveNext()) throw new StateError("More than one element"); |
221 return result; | 116 return result; |
222 } | 117 } |
223 | 118 |
224 static dynamic firstWhere(Iterable iterable, | 119 static dynamic firstWhere(Iterable iterable, |
225 bool test(dynamic value), | 120 bool test(dynamic value), |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 static Set setDifference(Set set, Set other, Set result) { | 320 static Set setDifference(Set set, Set other, Set result) { |
426 for (var element in set) { | 321 for (var element in set) { |
427 if (!other.contains(element)) { | 322 if (!other.contains(element)) { |
428 result.add(element); | 323 result.add(element); |
429 } | 324 } |
430 } | 325 } |
431 return result; | 326 return result; |
432 } | 327 } |
433 } | 328 } |
434 | 329 |
435 class Collections { | |
436 static String collectionToString(Collection c) | |
437 => ToString.collectionToString(c); | |
438 } | |
439 | |
440 /** | 330 /** |
441 * An unmodifiable [List] view of another List. | 331 * An unmodifiable [List] view of another List. |
442 * | 332 * |
443 * The source of the elements may be a [List] or any [Iterable] with | 333 * The source of the elements may be a [List] or any [Iterable] with |
444 * efficient [Iterable.length] and [Iterable.elementAt]. | 334 * efficient [Iterable.length] and [Iterable.elementAt]. |
445 */ | 335 */ |
446 class UnmodifiableListView<E> extends UnmodifiableListBase<E> { | 336 class UnmodifiableListView<E> extends UnmodifiableListBase<E> { |
447 Iterable<E> _source; | 337 Iterable<E> _source; |
448 /** Create an unmodifiable list backed by [source]. */ | 338 /** Create an unmodifiable list backed by [source]. */ |
449 UnmodifiableListView(Iterable<E> source) : _source = source; | 339 UnmodifiableListView(Iterable<E> source) : _source = source; |
450 int get length => _source.length; | 340 int get length => _source.length; |
451 E operator[](int index) => _source.elementAt(index); | 341 E operator[](int index) => _source.elementAt(index); |
452 } | 342 } |
OLD | NEW |