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