| 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). | |
| 9 * | |
| 10 * Once Dart receives Mixins it will be replaced with mixin classes. | |
| 11 */ | |
| 12 @deprecated | |
| 13 class IterableMixinWorkaround { | |
| 14 static bool contains(Iterable iterable, var element) { | |
| 15 for (final e in iterable) { | |
| 16 if (element == e) return true; | |
| 17 } | |
| 18 return false; | |
| 19 } | |
| 20 | |
| 21 static void forEach(Iterable iterable, void f(o)) { | |
| 22 for (final e in iterable) { | |
| 23 f(e); | |
| 24 } | |
| 25 } | |
| 26 | |
| 27 static bool any(Iterable iterable, bool f(o)) { | |
| 28 for (final e in iterable) { | |
| 29 if (f(e)) return true; | |
| 30 } | |
| 31 return false; | |
| 32 } | |
| 33 | |
| 34 static bool every(Iterable iterable, bool f(o)) { | |
| 35 for (final e in iterable) { | |
| 36 if (!f(e)) return false; | |
| 37 } | |
| 38 return true; | |
| 39 } | |
| 40 | |
| 41 static dynamic reduce(Iterable iterable, | |
| 42 dynamic combine(previousValue, element)) { | |
| 43 Iterator iterator = iterable.iterator; | |
| 44 if (!iterator.moveNext()) throw new StateError("No elements"); | |
| 45 var value = iterator.current; | |
| 46 while (iterator.moveNext()) { | |
| 47 value = combine(value, iterator.current); | |
| 48 } | |
| 49 return value; | |
| 50 } | |
| 51 | |
| 52 static dynamic fold(Iterable iterable, | |
| 53 dynamic initialValue, | |
| 54 dynamic combine(dynamic previousValue, element)) { | |
| 55 for (final element in iterable) { | |
| 56 initialValue = combine(initialValue, element); | |
| 57 } | |
| 58 return initialValue; | |
| 59 } | |
| 60 | |
| 61 /** | |
| 62 * Removes elements matching [test] from [list]. | |
| 63 * | |
| 64 * This is performed in two steps, to avoid exposing an inconsistent state | |
| 65 * to the [test] function. First the elements to retain are found, and then | |
| 66 * the original list is updated to contain those elements. | |
| 67 */ | |
| 68 static void removeWhereList(List list, bool test(var element)) { | |
| 69 List retained = []; | |
| 70 int length = list.length; | |
| 71 for (int i = 0; i < length; i++) { | |
| 72 var element = list[i]; | |
| 73 if (!test(element)) { | |
| 74 retained.add(element); | |
| 75 } | |
| 76 if (length != list.length) { | |
| 77 throw new ConcurrentModificationError(list); | |
| 78 } | |
| 79 } | |
| 80 if (retained.length == length) return; | |
| 81 list.length = retained.length; | |
| 82 for (int i = 0; i < retained.length; i++) { | |
| 83 list[i] = retained[i]; | |
| 84 } | |
| 85 } | |
| 86 | |
| 87 static bool isEmpty(Iterable iterable) { | |
| 88 return !iterable.iterator.moveNext(); | |
| 89 } | |
| 90 | |
| 91 static dynamic first(Iterable iterable) { | |
| 92 Iterator it = iterable.iterator; | |
| 93 if (!it.moveNext()) { | |
| 94 throw new StateError("No elements"); | |
| 95 } | |
| 96 return it.current; | |
| 97 } | |
| 98 | |
| 99 static dynamic last(Iterable iterable) { | |
| 100 Iterator it = iterable.iterator; | |
| 101 if (!it.moveNext()) { | |
| 102 throw new StateError("No elements"); | |
| 103 } | |
| 104 dynamic result; | |
| 105 do { | |
| 106 result = it.current; | |
| 107 } while(it.moveNext()); | |
| 108 return result; | |
| 109 } | |
| 110 | |
| 111 static dynamic single(Iterable iterable) { | |
| 112 Iterator it = iterable.iterator; | |
| 113 if (!it.moveNext()) throw new StateError("No elements"); | |
| 114 dynamic result = it.current; | |
| 115 if (it.moveNext()) throw new StateError("More than one element"); | |
| 116 return result; | |
| 117 } | |
| 118 | |
| 119 static dynamic firstWhere(Iterable iterable, | |
| 120 bool test(dynamic value), | |
| 121 dynamic orElse()) { | |
| 122 for (dynamic element in iterable) { | |
| 123 if (test(element)) return element; | |
| 124 } | |
| 125 if (orElse != null) return orElse(); | |
| 126 throw new StateError("No matching element"); | |
| 127 } | |
| 128 | |
| 129 static dynamic lastWhere(Iterable iterable, | |
| 130 bool test(dynamic value), | |
| 131 dynamic orElse()) { | |
| 132 dynamic result = null; | |
| 133 bool foundMatching = false; | |
| 134 for (dynamic element in iterable) { | |
| 135 if (test(element)) { | |
| 136 result = element; | |
| 137 foundMatching = true; | |
| 138 } | |
| 139 } | |
| 140 if (foundMatching) return result; | |
| 141 if (orElse != null) return orElse(); | |
| 142 throw new StateError("No matching element"); | |
| 143 } | |
| 144 | |
| 145 static dynamic lastWhereList(List list, | |
| 146 bool test(dynamic value), | |
| 147 dynamic orElse()) { | |
| 148 // TODO(floitsch): check that arguments are of correct type? | |
| 149 for (int i = list.length - 1; i >= 0; i--) { | |
| 150 dynamic element = list[i]; | |
| 151 if (test(element)) return element; | |
| 152 } | |
| 153 if (orElse != null) return orElse(); | |
| 154 throw new StateError("No matching element"); | |
| 155 } | |
| 156 | |
| 157 static dynamic singleWhere(Iterable iterable, bool test(dynamic value)) { | |
| 158 dynamic result = null; | |
| 159 bool foundMatching = false; | |
| 160 for (dynamic element in iterable) { | |
| 161 if (test(element)) { | |
| 162 if (foundMatching) { | |
| 163 throw new StateError("More than one matching element"); | |
| 164 } | |
| 165 result = element; | |
| 166 foundMatching = true; | |
| 167 } | |
| 168 } | |
| 169 if (foundMatching) return result; | |
| 170 throw new StateError("No matching element"); | |
| 171 } | |
| 172 | |
| 173 static dynamic elementAt(Iterable iterable, int index) { | |
| 174 if (index is! int || index < 0) throw new RangeError.value(index); | |
| 175 int remaining = index; | |
| 176 for (dynamic element in iterable) { | |
| 177 if (remaining == 0) return element; | |
| 178 remaining--; | |
| 179 } | |
| 180 throw new RangeError.value(index); | |
| 181 } | |
| 182 | |
| 183 static String join(Iterable iterable, [String separator]) { | |
| 184 StringBuffer buffer = new StringBuffer(); | |
| 185 buffer.writeAll(iterable, separator); | |
| 186 return buffer.toString(); | |
| 187 } | |
| 188 | |
| 189 static String joinList(List list, [String separator]) { | |
| 190 if (list.isEmpty) return ""; | |
| 191 if (list.length == 1) return "${list[0]}"; | |
| 192 StringBuffer buffer = new StringBuffer(); | |
| 193 if (separator.isEmpty) { | |
| 194 for (int i = 0; i < list.length; i++) { | |
| 195 buffer.write(list[i]); | |
| 196 } | |
| 197 } else { | |
| 198 buffer.write(list[0]); | |
| 199 for (int i = 1; i < list.length; i++) { | |
| 200 buffer.write(separator); | |
| 201 buffer.write(list[i]); | |
| 202 } | |
| 203 } | |
| 204 return buffer.toString(); | |
| 205 } | |
| 206 | |
| 207 static Iterable where(Iterable iterable, bool f(var element)) { | |
| 208 return new WhereIterable(iterable, f); | |
| 209 } | |
| 210 | |
| 211 static Iterable map(Iterable iterable, f(var element)) { | |
| 212 return new MappedIterable(iterable, f); | |
| 213 } | |
| 214 | |
| 215 static Iterable mapList(List list, f(var element)) { | |
| 216 return new MappedListIterable(list, f); | |
| 217 } | |
| 218 | |
| 219 static Iterable expand(Iterable iterable, Iterable f(var element)) { | |
| 220 return new ExpandIterable(iterable, f); | |
| 221 } | |
| 222 | |
| 223 static Iterable takeList(List list, int n) { | |
| 224 // The generic type is currently lost. It will be fixed with mixins. | |
| 225 return new SubListIterable(list, 0, n); | |
| 226 } | |
| 227 | |
| 228 static Iterable takeWhile(Iterable iterable, bool test(var value)) { | |
| 229 // The generic type is currently lost. It will be fixed with mixins. | |
| 230 return new TakeWhileIterable(iterable, test); | |
| 231 } | |
| 232 | |
| 233 static Iterable skipList(List list, int n) { | |
| 234 // The generic type is currently lost. It will be fixed with mixins. | |
| 235 return new SubListIterable(list, n, null); | |
| 236 } | |
| 237 | |
| 238 static Iterable skipWhile(Iterable iterable, bool test(var value)) { | |
| 239 // The generic type is currently lost. It will be fixed with mixins. | |
| 240 return new SkipWhileIterable(iterable, test); | |
| 241 } | |
| 242 | |
| 243 static Iterable reversedList(List list) { | |
| 244 return new ReversedListIterable(list); | |
| 245 } | |
| 246 | |
| 247 static void sortList(List list, int compare(a, b)) { | |
| 248 if (compare == null) compare = Comparable.compare; | |
| 249 Sort.sort(list, compare); | |
| 250 } | |
| 251 | |
| 252 static int indexOfList(List list, var element, int start) { | |
| 253 return Arrays.indexOf(list, element, start, list.length); | |
| 254 } | |
| 255 | |
| 256 static int lastIndexOfList(List list, var element, int start) { | |
| 257 if (start == null) start = list.length - 1; | |
| 258 return Arrays.lastIndexOf(list, element, start); | |
| 259 } | |
| 260 | |
| 261 static Iterable getRangeList(List list, int start, int end) { | |
| 262 if (start < 0 || start > list.length) { | |
| 263 throw new RangeError.range(start, 0, list.length); | |
| 264 } | |
| 265 if (end < start || end > list.length) { | |
| 266 throw new RangeError.range(end, start, list.length); | |
| 267 } | |
| 268 // The generic type is currently lost. It will be fixed with mixins. | |
| 269 return new SubListIterable(list, start, end); | |
| 270 } | |
| 271 | |
| 272 static void setRangeList(List list, int start, int length, | |
| 273 List from, int startFrom) { | |
| 274 if (length == 0) return; | |
| 275 | |
| 276 if (length < 0) throw new ArgumentError(length); | |
| 277 if (start < 0) throw new RangeError.value(start); | |
| 278 if (start + length > list.length) { | |
| 279 throw new RangeError.value(start + length); | |
| 280 } | |
| 281 | |
| 282 Arrays.copy(from, startFrom, list, start, length); | |
| 283 } | |
| 284 | |
| 285 static Map<int, dynamic> asMapList(List l) { | |
| 286 return new ListMapView(l); | |
| 287 } | |
| 288 | |
| 289 static bool setContainsAll(Set set, Iterable other) { | |
| 290 for (var element in other) { | |
| 291 if (!set.contains(element)) return false; | |
| 292 } | |
| 293 return true; | |
| 294 } | |
| 295 | |
| 296 static Set setIntersection(Set set, Set other, Set result) { | |
| 297 Set smaller; | |
| 298 Set larger; | |
| 299 if (set.length < other.length) { | |
| 300 smaller = set; | |
| 301 larger = other; | |
| 302 } else { | |
| 303 smaller = other; | |
| 304 larger = set; | |
| 305 } | |
| 306 for (var element in smaller) { | |
| 307 if (larger.contains(element)) { | |
| 308 result.add(element); | |
| 309 } | |
| 310 } | |
| 311 return result; | |
| 312 } | |
| 313 | |
| 314 static Set setUnion(Set set, Set other, Set result) { | |
| 315 result.addAll(set); | |
| 316 result.addAll(other); | |
| 317 return result; | |
| 318 } | |
| 319 | |
| 320 static Set setDifference(Set set, Set other, Set result) { | |
| 321 for (var element in set) { | |
| 322 if (!other.contains(element)) { | |
| 323 result.add(element); | |
| 324 } | |
| 325 } | |
| 326 return result; | |
| 327 } | |
| 328 } | |
| 329 | |
| 330 /** | |
| 331 * An unmodifiable [List] view of another List. | 8 * An unmodifiable [List] view of another List. |
| 332 * | 9 * |
| 333 * The source of the elements may be a [List] or any [Iterable] with | 10 * The source of the elements may be a [List] or any [Iterable] with |
| 334 * efficient [Iterable.length] and [Iterable.elementAt]. | 11 * efficient [Iterable.length] and [Iterable.elementAt]. |
| 335 */ | 12 */ |
| 336 class UnmodifiableListView<E> extends UnmodifiableListBase<E> { | 13 class UnmodifiableListView<E> extends UnmodifiableListBase<E> { |
| 337 Iterable<E> _source; | 14 Iterable<E> _source; |
| 338 /** Create an unmodifiable list backed by [source]. */ | 15 /** Create an unmodifiable list backed by [source]. */ |
| 339 UnmodifiableListView(Iterable<E> source) : _source = source; | 16 UnmodifiableListView(Iterable<E> source) : _source = source; |
| 340 int get length => _source.length; | 17 int get length => _source.length; |
| 341 E operator[](int index) => _source.elementAt(index); | 18 E operator[](int index) => _source.elementAt(index); |
| 342 } | 19 } |
| OLD | NEW |