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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 * instead of just repeatedly calling remove. | 67 * instead of just repeatedly calling remove. |
68 */ | 68 */ |
69 static void removeAllList(Collection collection, Iterable elementsToRemove) { | 69 static void removeAllList(Collection collection, Iterable elementsToRemove) { |
70 Set setToRemove; | 70 Set setToRemove; |
71 // Assume [contains] is efficient on a Set. | 71 // Assume [contains] is efficient on a Set. |
72 if (elementsToRemove is Set) { | 72 if (elementsToRemove is Set) { |
73 setToRemove = elementsToRemove; | 73 setToRemove = elementsToRemove; |
74 } else { | 74 } else { |
75 setToRemove = elementsToRemove.toSet(); | 75 setToRemove = elementsToRemove.toSet(); |
76 } | 76 } |
77 collection.removeMatching(setToRemove.contains); | 77 collection.removeWhere(setToRemove.contains); |
78 } | 78 } |
79 | 79 |
80 /** | 80 /** |
81 * Simple implemenation for [Collection.retainAll]. | 81 * Simple implemenation for [Collection.retainAll]. |
82 * | 82 * |
83 * This implementation assumes that [Collecton.retainMatching] on [collection] | 83 * This implementation assumes that [Collecton.retainWhere] on [collection] |
84 * is efficient. | 84 * is efficient. |
85 */ | 85 */ |
86 static void retainAll(Collection collection, Iterable elementsToRetain) { | 86 static void retainAll(Collection collection, Iterable elementsToRetain) { |
87 Set lookup; | 87 Set lookup; |
88 if (elementsToRetain is Set) { | 88 if (elementsToRetain is Set) { |
89 lookup = elementsToRetain; | 89 lookup = elementsToRetain; |
90 } else { | 90 } else { |
91 lookup = elementsToRetain.toSet(); | 91 lookup = elementsToRetain.toSet(); |
92 } | 92 } |
93 if (lookup.isEmpty) { | 93 if (lookup.isEmpty) { |
94 collection.clear(); | 94 collection.clear(); |
95 return; | 95 return; |
96 } | 96 } |
97 collection.retainMatching(lookup.contains); | 97 collection.retainWhere(lookup.contains); |
98 } | 98 } |
99 | 99 |
100 /** | 100 /** |
101 * Simple implemenation for [Collection.removeMatching]. | 101 * Simple implemenation for [Collection.removeWhere]. |
102 * | 102 * |
103 * This implementation assumes that [Collecton.removeAll] on [collection] is | 103 * This implementation assumes that [Collecton.removeAll] on [collection] is |
104 * efficient. | 104 * efficient. |
105 */ | 105 */ |
106 static void removeMatching(Collection collection, bool test(var element)) { | 106 static void removeWhere(Collection collection, bool test(var element)) { |
107 List elementsToRemove = []; | 107 List elementsToRemove = []; |
108 for (var element in collection) { | 108 for (var element in collection) { |
109 if (test(element)) elementsToRemove.add(element); | 109 if (test(element)) elementsToRemove.add(element); |
110 } | 110 } |
111 collection.removeAll(elementsToRemove); | 111 collection.removeAll(elementsToRemove); |
112 } | 112 } |
113 | 113 |
114 /** | 114 /** |
115 * Removes elements matching [test] from [list]. | 115 * Removes elements matching [test] from [list]. |
116 * | 116 * |
117 * This is performed in two steps, to avoid exposing an inconsistent state | 117 * This is performed in two steps, to avoid exposing an inconsistent state |
118 * to the [test] function. First the elements to retain are found, and then | 118 * to the [test] function. First the elements to retain are found, and then |
119 * the original list is updated to contain those elements. | 119 * the original list is updated to contain those elements. |
120 */ | 120 */ |
121 static void removeMatchingList(List list, bool test(var element)) { | 121 static void removeWhereList(List list, bool test(var element)) { |
122 List retained = []; | 122 List retained = []; |
123 int length = list.length; | 123 int length = list.length; |
124 for (int i = 0; i < length; i++) { | 124 for (int i = 0; i < length; i++) { |
125 var element = list[i]; | 125 var element = list[i]; |
126 if (!test(element)) { | 126 if (!test(element)) { |
127 retained.add(element); | 127 retained.add(element); |
128 } | 128 } |
129 if (length != list.length) { | 129 if (length != list.length) { |
130 throw new ConcurrentModificationError(list); | 130 throw new ConcurrentModificationError(list); |
131 } | 131 } |
132 } | 132 } |
133 if (retained.length == length) return; | 133 if (retained.length == length) return; |
134 list.length = retained.length; | 134 list.length = retained.length; |
135 for (int i = 0; i < retained.length; i++) { | 135 for (int i = 0; i < retained.length; i++) { |
136 list[i] = retained[i]; | 136 list[i] = retained[i]; |
137 } | 137 } |
138 } | 138 } |
139 | 139 |
140 /** | 140 /** |
141 * Simple implemenation for [Collection.retainMatching]. | 141 * Simple implemenation for [Collection.retainWhere]. |
142 * | 142 * |
143 * This implementation assumes that [Collecton.removeAll] on [collection] is | 143 * This implementation assumes that [Collecton.removeAll] on [collection] is |
144 * efficient. | 144 * efficient. |
145 */ | 145 */ |
146 static void retainMatching(Collection collection, bool test(var element)) { | 146 static void retainWhere(Collection collection, bool test(var element)) { |
147 List elementsToRemove = []; | 147 List elementsToRemove = []; |
148 for (var element in collection) { | 148 for (var element in collection) { |
149 if (!test(element)) elementsToRemove.add(element); | 149 if (!test(element)) elementsToRemove.add(element); |
150 } | 150 } |
151 collection.removeAll(elementsToRemove); | 151 collection.removeAll(elementsToRemove); |
152 } | 152 } |
153 | 153 |
154 static bool isEmpty(Iterable iterable) { | 154 static bool isEmpty(Iterable iterable) { |
155 return !iterable.iterator.moveNext(); | 155 return !iterable.iterator.moveNext(); |
156 } | 156 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 } | 202 } |
203 | 203 |
204 static dynamic single(Iterable iterable) { | 204 static dynamic single(Iterable iterable) { |
205 Iterator it = iterable.iterator; | 205 Iterator it = iterable.iterator; |
206 if (!it.moveNext()) throw new StateError("No elements"); | 206 if (!it.moveNext()) throw new StateError("No elements"); |
207 dynamic result = it.current; | 207 dynamic result = it.current; |
208 if (it.moveNext()) throw new StateError("More than one element"); | 208 if (it.moveNext()) throw new StateError("More than one element"); |
209 return result; | 209 return result; |
210 } | 210 } |
211 | 211 |
212 static dynamic firstMatching(Iterable iterable, | 212 static dynamic firstWhere(Iterable iterable, |
213 bool test(dynamic value), | 213 bool test(dynamic value), |
214 dynamic orElse()) { | 214 dynamic orElse()) { |
215 for (dynamic element in iterable) { | 215 for (dynamic element in iterable) { |
216 if (test(element)) return element; | 216 if (test(element)) return element; |
217 } | 217 } |
218 if (orElse != null) return orElse(); | 218 if (orElse != null) return orElse(); |
219 throw new StateError("No matching element"); | 219 throw new StateError("No matching element"); |
220 } | 220 } |
221 | 221 |
222 static dynamic lastMatching(Iterable iterable, | 222 static dynamic lastWhere(Iterable iterable, |
223 bool test(dynamic value), | 223 bool test(dynamic value), |
224 dynamic orElse()) { | 224 dynamic orElse()) { |
225 dynamic result = null; | 225 dynamic result = null; |
226 bool foundMatching = false; | 226 bool foundMatching = false; |
227 for (dynamic element in iterable) { | 227 for (dynamic element in iterable) { |
228 if (test(element)) { | 228 if (test(element)) { |
229 result = element; | 229 result = element; |
230 foundMatching = true; | 230 foundMatching = true; |
231 } | 231 } |
232 } | 232 } |
233 if (foundMatching) return result; | 233 if (foundMatching) return result; |
234 if (orElse != null) return orElse(); | 234 if (orElse != null) return orElse(); |
235 throw new StateError("No matching element"); | 235 throw new StateError("No matching element"); |
236 } | 236 } |
237 | 237 |
238 static dynamic lastMatchingInList(List list, | 238 static dynamic lastWhereList(List list, |
239 bool test(dynamic value), | 239 bool test(dynamic value), |
240 dynamic orElse()) { | 240 dynamic orElse()) { |
241 // TODO(floitsch): check that arguments are of correct type? | 241 // TODO(floitsch): check that arguments are of correct type? |
242 for (int i = list.length - 1; i >= 0; i--) { | 242 for (int i = list.length - 1; i >= 0; i--) { |
243 dynamic element = list[i]; | 243 dynamic element = list[i]; |
244 if (test(element)) return element; | 244 if (test(element)) return element; |
245 } | 245 } |
246 if (orElse != null) return orElse(); | 246 if (orElse != null) return orElse(); |
247 throw new StateError("No matching element"); | 247 throw new StateError("No matching element"); |
248 } | 248 } |
249 | 249 |
250 static dynamic singleMatching(Iterable iterable, bool test(dynamic value)) { | 250 static dynamic singleWhere(Iterable iterable, bool test(dynamic value)) { |
251 dynamic result = null; | 251 dynamic result = null; |
252 bool foundMatching = false; | 252 bool foundMatching = false; |
253 for (dynamic element in iterable) { | 253 for (dynamic element in iterable) { |
254 if (test(element)) { | 254 if (test(element)) { |
255 if (foundMatching) { | 255 if (foundMatching) { |
256 throw new StateError("More than one matching element"); | 256 throw new StateError("More than one matching element"); |
257 } | 257 } |
258 result = element; | 258 result = element; |
259 foundMatching = true; | 259 foundMatching = true; |
260 } | 260 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 * The source of the elements may be a [List] or any [Iterable] with | 394 * The source of the elements may be a [List] or any [Iterable] with |
395 * efficient [Iterable.length] and [Iterable.elementAt]. | 395 * efficient [Iterable.length] and [Iterable.elementAt]. |
396 */ | 396 */ |
397 class UnmodifiableListView<E> extends UnmodifiableListBase<E> { | 397 class UnmodifiableListView<E> extends UnmodifiableListBase<E> { |
398 Iterable<E> _source; | 398 Iterable<E> _source; |
399 /** Create an unmodifiable list backed by [source]. */ | 399 /** Create an unmodifiable list backed by [source]. */ |
400 UnmodifiableListView(Iterable<E> source) : _source = source; | 400 UnmodifiableListView(Iterable<E> source) : _source = source; |
401 int get length => _source.length; | 401 int get length => _source.length; |
402 E operator[](int index) => _source.elementAt(index); | 402 E operator[](int index) => _source.elementAt(index); |
403 } | 403 } |
OLD | NEW |