Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: sdk/lib/collection/set.dart

Issue 289353002: Add SetBase/SetMixin. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated to not use cloneEmpty Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
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.
4
5 /**
6 * Base implementations of [Set].
7 */
8 part of dart.collection;
9
10 /**
11 * Mixin implementation of [Set].
12 *
13 * This class provides a base implementation of a `Set` that depends only
14 * on the abstract members: [add], [contains], [lookup], [remove],
15 * [iterator], [length] and [toSet].
16 *
17 * Implementations of `Set` using this mixin should consider also implementing
18 * `clear` in constant time. The default implementation works by removing every
19 * element.
20 *
21 */
22 abstract class SetMixin<E> implements Set<E> {
23 // This class reimplements all of [IterableMixin].
24 // If/when Dart mixins get more powerful, we should just create a single
25 // Mixin class from IterableMixin and the new methods of thisclass.
26
27 bool add(E element);
28
29 bool contains(Object element);
30
31 E lookup(E element);
32
33 bool remove(Object element);
34
35 Iterable<E> get iterator;
36
37 Set<E> toSet();
38
39 int get length;
40
41 bool get isEmpty => length == 0;
42
43 bool get isNotEmpty => length != 0;
44
45 void clear() {
46 removeAll(toList());
47 }
48
49 void addAll(Iterable<E> elements) {
50 for (E element in elements) add(element);
51 }
52
53 void removeAll(Iterable<Object> elements) {
54 for (Object element in elements) remove(element);
55 }
56
57 void retainAll(Iterable<Object> elements) {
58 // Create a copy of the set, remove all of elements from the copy,
59 // then remove all remaining elements in copy from this.
60 Set<E> toRemove = toSet();
61 for (Object o in elements) {
62 toRemove.remove(o);
63 }
64 removeAll(toRemove);
65 }
66
67 void removeWhere(bool test(E element)) {
68 List toRemove = [];
69 for (E element in this) {
70 if (test(element)) toRemove.add(element);
71 }
72 removeAll(toRemove);
73 }
74
75 void retainWhere(bool test(E element)) {
76 List toRemove = [];
77 for (E element in this) {
78 if (!test(element)) toRemove.add(element);
79 }
80 removeAll(toRemove);
81 }
82
83 bool containsAll(Iterable<Object> other) {
84 for (Object o in other) {
85 if (!contains(o)) return false;
86 }
87 return true;
88 }
89
90 Set<E> union(Set<E> other) {
91 return toSet()..addAll(other);
92 }
93
94 Set<E> intersection(Set<Object> other) {
95 Set<E> result = toSet();
96 for (E element in this) {
97 if (!other.contains(element)) result.remove(element);
98 }
99 return result;
100 }
101
102 Set<E> difference(Set<Object> other) {
103 Set<E> result = toSet();
104 for (E element in this) {
105 if (other.contains(element)) result.remove(element);
106 }
107 return result;
108 }
109
110 List<E> toList({bool growable: true}) {
111 List<E> result = growable ? (new List<E>()..length = length)
112 : new List<E>(length);
113 int i = 0;
114 for (E element in this) result[i++] = element;
115 return result;
116 }
117
118 Iterable map(f(E element)) =>
119 new EfficientLengthMappedIterable<E, dynamic>(this, f);
120
121 E get single {
122 if (length > 1) throw IterableElementError.tooMany();
123 Iterator it = iterator;
124 if (!it.moveNext()) throw IterableElementError.noElement();
125 E result = it.current;
126 return result;
127 }
128
129 String toString() => IterableMixinWorkaround.toStringIterable(this, '{', '}');
130
131 // Copied from IterableMixin.
Søren Gjesse 2014/05/22 09:25:52 Is there a comment in IterableMixin to make sure t
Lasse Reichstein Nielsen 2014/05/22 09:41:37 Is now.
132 // Should be inherited if we had multi-level mixins.
133
134 Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
135
136 Iterable expand(Iterable f(E element)) =>
137 new ExpandIterable<E, dynamic>(this, f);
138
139 void forEach(void f(E element)) {
140 for (E element in this) f(element);
141 }
142
143 E reduce(E combine(E value, E element)) {
144 Iterator<E> iterator = this.iterator;
145 if (!iterator.moveNext()) {
146 throw IterableElementError.noElement();
147 }
148 E value = iterator.current;
149 while (iterator.moveNext()) {
150 value = combine(value, iterator.current);
151 }
152 return value;
153 }
154
155 dynamic fold(var initialValue,
156 dynamic combine(var previousValue, E element)) {
157 var value = initialValue;
158 for (E element in this) value = combine(value, element);
159 return value;
160 }
161
162 bool every(bool f(E element)) {
163 for (E element in this) {
164 if (!f(element)) return false;
165 }
166 return true;
167 }
168
169 String join([String separator = ""]) {
170 Iterator<E> iterator = this.iterator;
171 if (!iterator.moveNext()) return "";
172 StringBuffer buffer = new StringBuffer();
173 if (separator == null || separator == "") {
174 do {
175 buffer.write("${iterator.current}");
176 } while (iterator.moveNext());
177 } else {
178 buffer.write("${iterator.current}");
179 while (iterator.moveNext()) {
180 buffer.write(separator);
181 buffer.write("${iterator.current}");
182 }
183 }
184 return buffer.toString();
185 }
186
187 bool any(bool test(E element)) {
188 for (E element in this) {
189 if (test(element)) return true;
190 }
191 return false;
192 }
193
194 Iterable<E> take(int n) {
195 return new TakeIterable<E>(this, n);
196 }
197
198 Iterable<E> takeWhile(bool test(E value)) {
199 return new TakeWhileIterable<E>(this, test);
200 }
201
202 Iterable<E> skip(int n) {
203 return new SkipIterable<E>(this, n);
204 }
205
206 Iterable<E> skipWhile(bool test(E value)) {
207 return new SkipWhileIterable<E>(this, test);
208 }
209
210 E get first {
211 Iterator it = iterator;
212 if (!it.moveNext()) {
213 throw IterableElementError.noElement();
214 }
215 return it.current;
216 }
217
218 E get last {
219 Iterator it = iterator;
220 if (!it.moveNext()) {
221 throw IterableElementError.noElement();
222 }
223 E result;
224 do {
225 result = it.current;
226 } while(it.moveNext());
227 return result;
228 }
229
230 dynamic firstWhere(bool test(E value), { Object orElse() }) {
231 for (E element in this) {
232 if (test(element)) return element;
233 }
234 if (orElse != null) return orElse();
235 throw IterableElementError.noElement();
236 }
237
238 dynamic lastWhere(bool test(E value), { Object orElse() }) {
239 E result = null;
240 bool foundMatching = false;
241 for (E element in this) {
242 if (test(element)) {
243 result = element;
244 foundMatching = true;
245 }
246 }
247 if (foundMatching) return result;
248 if (orElse != null) return orElse();
249 throw IterableElementError.noElement();
250 }
251
252 E singleWhere(bool test(E value)) {
253 E result = null;
254 bool foundMatching = false;
255 for (E element in this) {
256 if (test(element)) {
257 if (foundMatching) {
258 throw IterableElementError.tooMany();
259 }
260 result = element;
261 foundMatching = true;
262 }
263 }
264 if (foundMatching) return result;
265 throw IterableElementError.noElement();
266 }
267
268 E elementAt(int index) {
269 if (index is! int || index < 0) throw new RangeError.value(index);
270 int remaining = index;
271 for (E element in this) {
272 if (remaining == 0) return element;
273 remaining--;
274 }
275 throw new RangeError.value(index);
276 }
277 }
278
279 /**
280 * Base implementation of [Set].
281 *
282 * This class provides a base implementation of a `Set` that depends only
283 * on the abstract members: [add], [contains], [lookup], [remove],
284 * [iterator], [length] and [toSet].
285 *
286 * Implementations of `Set` using this base should consider also implementing
287 * `clear` in constant time. The default implementation works by removing every
288 * element.
289 */
290 abstract class SetBase<E> = Object with SetMixin<E>;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698