| 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 |