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 * The [Collections] class implements static methods useful when | 8 * The [Collections] class implements static methods useful when |
9 * writing a class that implements [Collection] and the [iterator] | 9 * writing a class that implements [Collection] and the [iterator] |
10 * method. | 10 * method. |
11 */ | 11 */ |
12 class Collections { | 12 class Collections { |
13 static bool contains(Iterable iterable, var element) { | 13 static bool contains(Iterable iterable, var element) { |
14 for (final e in iterable) { | 14 for (final e in iterable) { |
15 if (element == e) return true; | 15 if (element == e) return true; |
16 } | 16 } |
17 return false; | 17 return false; |
18 } | 18 } |
19 | 19 |
20 static void forEach(Iterable iterable, void f(o)) { | 20 static void forEach(Iterable iterable, void f(o)) { |
21 for (final e in iterable) { | 21 for (final e in iterable) { |
22 f(e); | 22 f(e); |
23 } | 23 } |
24 } | 24 } |
25 | 25 |
26 static bool some(Iterable iterable, bool f(o)) { | 26 static bool any(Iterable iterable, bool f(o)) { |
27 for (final e in iterable) { | 27 for (final e in iterable) { |
28 if (f(e)) return true; | 28 if (f(e)) return true; |
29 } | 29 } |
30 return false; | 30 return false; |
31 } | 31 } |
32 | 32 |
33 static bool every(Iterable iterable, bool f(o)) { | 33 static bool every(Iterable iterable, bool f(o)) { |
34 for (final e in iterable) { | 34 for (final e in iterable) { |
35 if (!f(e)) return false; | 35 if (!f(e)) return false; |
36 } | 36 } |
37 return true; | 37 return true; |
38 } | 38 } |
39 | 39 |
40 static List map(Iterable source, List destination, f(o)) { | |
41 for (final e in source) { | |
42 destination.add(f(e)); | |
43 } | |
44 return destination; | |
45 } | |
46 | |
47 static dynamic reduce(Iterable iterable, | 40 static dynamic reduce(Iterable iterable, |
48 dynamic initialValue, | 41 dynamic initialValue, |
49 dynamic combine(dynamic previousValue, element)) { | 42 dynamic combine(dynamic previousValue, element)) { |
50 for (final element in iterable) { | 43 for (final element in iterable) { |
51 initialValue = combine(initialValue, element); | 44 initialValue = combine(initialValue, element); |
52 } | 45 } |
53 return initialValue; | 46 return initialValue; |
54 } | 47 } |
55 | 48 |
56 static List filter(Iterable source, List destination, bool f(o)) { | 49 static bool isEmpty(Iterable iterable) { |
57 for (final e in source) { | 50 return !iterable.iterator.moveNext(); |
58 if (f(e)) destination.add(e); | |
59 } | |
60 return destination; | |
61 } | 51 } |
62 | 52 |
63 static bool isEmpty(Iterable iterable) { | 53 static dynamic first(Iterable iterable) { |
64 return !iterable.iterator().hasNext; | 54 Iterator it = iterable.iterator; |
| 55 if (!it.moveNext()) { |
| 56 throw new StateError("No elements"); |
| 57 } |
| 58 return it.current; |
| 59 } |
| 60 |
| 61 static dynamic last(Iterable iterable) { |
| 62 Iterator it = iterable.iterator; |
| 63 if (!it.moveNext()) { |
| 64 throw new StateError("No elements"); |
| 65 } |
| 66 dynamic result; |
| 67 do { |
| 68 result = it.current; |
| 69 } while(it.moveNext()); |
| 70 return result; |
| 71 } |
| 72 |
| 73 static dynamic min(Iterable iterable, [int compare(var a, var b)]) { |
| 74 if (compare == null) compare = Comparable.compare; |
| 75 Iterator it = iterable.iterator; |
| 76 if (!it.moveNext()) { |
| 77 return null; |
| 78 } |
| 79 var min = it.current; |
| 80 while (it.moveNext()) { |
| 81 if (compare(min, it.current) > 0) min = it.current; |
| 82 } |
| 83 return min; |
| 84 } |
| 85 |
| 86 static dynamic max(Iterable iterable, [int compare(var a, var b)]) { |
| 87 if (compare == null) compare = Comparable.compare; |
| 88 Iterator it = iterable.iterator; |
| 89 if (!it.moveNext()) { |
| 90 return null; |
| 91 } |
| 92 var max = it.current; |
| 93 while (it.moveNext()) { |
| 94 if (compare(max, it.current) < 0) max = it.current; |
| 95 } |
| 96 return max; |
| 97 } |
| 98 |
| 99 static dynamic single(Iterable iterable) { |
| 100 Iterator it = iterable.iterator; |
| 101 if (!it.moveNext()) throw new StateError("No elements"); |
| 102 dynamic result = it.current; |
| 103 if (it.moveNext()) throw new StateError("More than one element"); |
| 104 return result; |
| 105 } |
| 106 |
| 107 static dynamic firstMatching(Iterable iterable, |
| 108 bool test(dynamic value), |
| 109 dynamic orElse()) { |
| 110 for (dynamic element in iterable) { |
| 111 if (test(element)) return element; |
| 112 } |
| 113 if (orElse != null) return orElse(); |
| 114 throw new StateError("No matching element"); |
| 115 } |
| 116 |
| 117 static dynamic lastMatching(Iterable iterable, |
| 118 bool test(dynamic value), |
| 119 dynamic orElse()) { |
| 120 dynamic result = null; |
| 121 bool foundMatching = false; |
| 122 for (dynamic element in iterable) { |
| 123 if (test(element)) { |
| 124 result = element; |
| 125 foundMatching = true; |
| 126 } |
| 127 } |
| 128 if (foundMatching) return result; |
| 129 if (orElse != null) return orElse(); |
| 130 throw new StateError("No matching element"); |
| 131 } |
| 132 |
| 133 static dynamic lastMatchingInList(List list, |
| 134 bool test(dynamic value), |
| 135 dynamic orElse()) { |
| 136 // TODO(floitsch): check that arguments are of correct type? |
| 137 for (int i = list.length - 1; i >= 0; i--) { |
| 138 dynamic element = list[i]; |
| 139 if (test(element)) return element; |
| 140 } |
| 141 if (orElse != null) return orElse(); |
| 142 throw new StateError("No matching element"); |
| 143 } |
| 144 |
| 145 static dynamic singleMatching(Iterable iterable, bool test(dynamic value)) { |
| 146 dynamic result = null; |
| 147 bool foundMatching = false; |
| 148 for (dynamic element in iterable) { |
| 149 if (test(element)) { |
| 150 if (foundMatching) { |
| 151 throw new StateError("More than one matching element"); |
| 152 } |
| 153 result = element; |
| 154 foundMatching = true; |
| 155 } |
| 156 } |
| 157 if (foundMatching) return result; |
| 158 throw new StateError("No matching element"); |
| 159 } |
| 160 |
| 161 static dynamic elementAt(Iterable iterable, int index) { |
| 162 if (index is! int || index < 0) throw new RangeError.value(index); |
| 163 int remaining = index; |
| 164 for (dynamic element in iterable) { |
| 165 if (remaining == 0) return element; |
| 166 remaining--; |
| 167 } |
| 168 throw new RangeError.value(index); |
| 169 } |
| 170 |
| 171 static String join(Iterable iterable, [String separator]) { |
| 172 Iterator iterator = iterable.iterator; |
| 173 if (!iterator.moveNext()) return ""; |
| 174 StringBuffer buffer = new StringBuffer(); |
| 175 if (separator == null || separator == "") { |
| 176 do { |
| 177 buffer.add("${iterator.current}"); |
| 178 } while (iterator.moveNext()); |
| 179 } else { |
| 180 buffer.add("${iterator.current}"); |
| 181 while (iterator.moveNext()) { |
| 182 buffer.add(separator); |
| 183 buffer.add("${iterator.current}"); |
| 184 } |
| 185 } |
| 186 return buffer.toString(); |
| 187 } |
| 188 |
| 189 static String joinList(List<Object> list, [String separator]) { |
| 190 if (list.isEmpty) return ""; |
| 191 if (list.length == 1) return "${list[0]}"; |
| 192 StringBuffer buffer = new StringBuffer(); |
| 193 if (separator == null || separator == "") { |
| 194 for (int i = 0; i < list.length; i++) { |
| 195 buffer.add("${list[i]}"); |
| 196 } |
| 197 } else { |
| 198 buffer.add("${list[0]}"); |
| 199 for (int i = 1; i < list.length; i++) { |
| 200 buffer.add(separator); |
| 201 buffer.add("${list[i]}"); |
| 202 } |
| 203 } |
| 204 return buffer.toString(); |
65 } | 205 } |
66 | 206 |
67 // TODO(jjb): visiting list should be an identityHashSet when it exists | 207 // TODO(jjb): visiting list should be an identityHashSet when it exists |
68 | 208 |
69 /** | 209 /** |
70 * Returns a string representing the specified collection. If the | 210 * Returns a string representing the specified collection. If the |
71 * collection is a [List], the returned string looks like this: | 211 * collection is a [List], the returned string looks like this: |
72 * [:'[element0, element1, ... elementN]':]. The value returned by its | 212 * [:'[element0, element1, ... elementN]':]. The value returned by its |
73 * [toString] method is used to represent each element. If the specified | 213 * [toString] method is used to represent each element. If the specified |
74 * collection is not a list, the returned string looks like this: | 214 * collection is not a list, the returned string looks like this: |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 * Returns true if the specified collection contains the specified object | 297 * Returns true if the specified collection contains the specified object |
158 * reference. | 298 * reference. |
159 */ | 299 */ |
160 static _containsRef(Collection c, Object ref) { | 300 static _containsRef(Collection c, Object ref) { |
161 for (var e in c) { | 301 for (var e in c) { |
162 if (identical(e, ref)) return true; | 302 if (identical(e, ref)) return true; |
163 } | 303 } |
164 return false; | 304 return false; |
165 } | 305 } |
166 } | 306 } |
OLD | NEW |