| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 import "dart:collection"; | 5 import "dart:collection"; |
| 6 import "dart:math" as math; | 6 import "dart:math" as math; |
| 7 | 7 |
| 8 import "unmodifiable_wrappers.dart"; | 8 import "unmodifiable_wrappers.dart"; |
| 9 | 9 |
| 10 typedef K _KeyForValue<K, V>(V value); |
| 11 |
| 10 /// A base class for delegating iterables. | 12 /// A base class for delegating iterables. |
| 11 /// | 13 /// |
| 12 /// Subclasses can provide a [_base] that should be delegated to. Unlike | 14 /// Subclasses can provide a [_base] that should be delegated to. Unlike |
| 13 /// [DelegatingIterable], this allows the base to be created on demand. | 15 /// [DelegatingIterable], this allows the base to be created on demand. |
| 14 abstract class _DelegatingIterableBase<E> implements Iterable<E> { | 16 abstract class _DelegatingIterableBase<E> implements Iterable<E> { |
| 15 Iterable<E> get _base; | 17 Iterable<E> get _base; |
| 16 | 18 |
| 17 const _DelegatingIterableBase(); | 19 const _DelegatingIterableBase(); |
| 18 | 20 |
| 19 bool any(bool test(E element)) => _base.any(test); | 21 bool any(bool test(E element)) => _base.any(test); |
| 20 | 22 |
| 21 bool contains(Object element) => _base.contains(element); | 23 bool contains(Object element) => _base.contains(element); |
| 22 | 24 |
| 23 E elementAt(int index) => _base.elementAt(index); | 25 E elementAt(int index) => _base.elementAt(index); |
| 24 | 26 |
| 25 bool every(bool test(E element)) => _base.every(test); | 27 bool every(bool test(E element)) => _base.every(test); |
| 26 | 28 |
| 27 Iterable expand(Iterable f(E element)) => _base.expand(f); | 29 Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element)) => |
| 30 _base.expand(f); |
| 28 | 31 |
| 29 E get first => _base.first; | 32 E get first => _base.first; |
| 30 | 33 |
| 31 E firstWhere(bool test(E element), {E orElse()}) => | 34 E firstWhere(bool test(E element), {E orElse()}) => |
| 32 _base.firstWhere(test, orElse: orElse); | 35 _base.firstWhere(test, orElse: orElse); |
| 33 | 36 |
| 34 fold(initialValue, combine(previousValue, E element)) => | 37 /*=T*/ fold/*<T>*/( |
| 38 /*=T*/ initialValue, |
| 39 /*=T*/ combine(/*=T*/ previousValue, E element)) => |
| 35 _base.fold(initialValue, combine); | 40 _base.fold(initialValue, combine); |
| 36 | 41 |
| 37 void forEach(void f(E element)) => _base.forEach(f); | 42 void forEach(void f(E element)) => _base.forEach(f); |
| 38 | 43 |
| 39 bool get isEmpty => _base.isEmpty; | 44 bool get isEmpty => _base.isEmpty; |
| 40 | 45 |
| 41 bool get isNotEmpty => _base.isNotEmpty; | 46 bool get isNotEmpty => _base.isNotEmpty; |
| 42 | 47 |
| 43 Iterator<E> get iterator => _base.iterator; | 48 Iterator<E> get iterator => _base.iterator; |
| 44 | 49 |
| 45 String join([String separator = ""]) => _base.join(separator); | 50 String join([String separator = ""]) => _base.join(separator); |
| 46 | 51 |
| 47 E get last => _base.last; | 52 E get last => _base.last; |
| 48 | 53 |
| 49 E lastWhere(bool test(E element), {E orElse()}) => | 54 E lastWhere(bool test(E element), {E orElse()}) => |
| 50 _base.lastWhere(test, orElse: orElse); | 55 _base.lastWhere(test, orElse: orElse); |
| 51 | 56 |
| 52 int get length => _base.length; | 57 int get length => _base.length; |
| 53 | 58 |
| 54 Iterable map(f(E element)) => _base.map(f); | 59 Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) => _base.map(f); |
| 55 | 60 |
| 56 E reduce(E combine(E value, E element)) => _base.reduce(combine); | 61 E reduce(E combine(E value, E element)) => _base.reduce(combine); |
| 57 | 62 |
| 58 E get single => _base.single; | 63 E get single => _base.single; |
| 59 | 64 |
| 60 E singleWhere(bool test(E element)) => _base.singleWhere(test); | 65 E singleWhere(bool test(E element)) => _base.singleWhere(test); |
| 61 | 66 |
| 62 Iterable<E> skip(int n) => _base.skip(n); | 67 Iterable<E> skip(int n) => _base.skip(n); |
| 63 | 68 |
| 64 Iterable<E> skipWhile(bool test(E value)) => _base.skipWhile(test); | 69 Iterable<E> skipWhile(bool test(E value)) => _base.skipWhile(test); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 /// | 389 /// |
| 385 /// That is, the returned set contains all the elements of this [Set] and all | 390 /// That is, the returned set contains all the elements of this [Set] and all |
| 386 /// the elements of [other]. | 391 /// the elements of [other]. |
| 387 /// | 392 /// |
| 388 /// Note that the returned set will use the default equality operation, which | 393 /// Note that the returned set will use the default equality operation, which |
| 389 /// may be different than the equality operation [this] uses. | 394 /// may be different than the equality operation [this] uses. |
| 390 Set<E> union(Set<E> other) => toSet()..addAll(other); | 395 Set<E> union(Set<E> other) => toSet()..addAll(other); |
| 391 } | 396 } |
| 392 | 397 |
| 393 /// Creates a modifiable [Set] view of the values of a [Map]. | 398 /// Creates a modifiable [Set] view of the values of a [Map]. |
| 394 /// | 399 /// |
| 395 /// The `Set` view assumes that the keys of the `Map` can be uniquely determined | 400 /// The `Set` view assumes that the keys of the `Map` can be uniquely determined |
| 396 /// from the values. The `keyForValue` function passed to the constructor finds | 401 /// from the values. The `keyForValue` function passed to the constructor finds |
| 397 /// the key for a single value. The `keyForValue` function should be consistent | 402 /// the key for a single value. The `keyForValue` function should be consistent |
| 398 /// with equality. If `value1 == value2` then `keyForValue(value1)` and | 403 /// with equality. If `value1 == value2` then `keyForValue(value1)` and |
| 399 /// `keyForValue(value2)` should be considered equal keys by the underlying map, | 404 /// `keyForValue(value2)` should be considered equal keys by the underlying map, |
| 400 /// and vice versa. | 405 /// and vice versa. |
| 401 /// | 406 /// |
| 402 /// Modifying the set will modify the underlying map based on the key returned | 407 /// Modifying the set will modify the underlying map based on the key returned |
| 403 /// by `keyForValue`. | 408 /// by `keyForValue`. |
| 404 /// | 409 /// |
| 405 /// If the `Map` contents are not compatible with the `keyForValue` function, | 410 /// If the `Map` contents are not compatible with the `keyForValue` function, |
| 406 /// the set will not work consistently, and may give meaningless responses or do | 411 /// the set will not work consistently, and may give meaningless responses or do |
| 407 /// inconsistent updates. | 412 /// inconsistent updates. |
| 408 /// | 413 /// |
| 409 /// This set can, for example, be used on a map from database record IDs to the | 414 /// This set can, for example, be used on a map from database record IDs to the |
| 410 /// records. It exposes the records as a set, and allows for writing both | 415 /// records. It exposes the records as a set, and allows for writing both |
| 411 /// `recordSet.add(databaseRecord)` and `recordMap[id]`. | 416 /// `recordSet.add(databaseRecord)` and `recordMap[id]`. |
| 412 /// | 417 /// |
| 413 /// Effectively, the map will act as a kind of index for the set. | 418 /// Effectively, the map will act as a kind of index for the set. |
| 414 class MapValueSet<K, V> extends _DelegatingIterableBase<V> implements Set<V> { | 419 class MapValueSet<K, V> extends _DelegatingIterableBase<V> implements Set<V> { |
| 415 final Map<K, V> _baseMap; | 420 final Map<K, V> _baseMap; |
| 416 final Function _keyForValue; | 421 final _KeyForValue<K, V> _keyForValue; |
| 417 | 422 |
| 418 /// Creates a new [MapValueSet] based on [base]. | 423 /// Creates a new [MapValueSet] based on [base]. |
| 419 /// | 424 /// |
| 420 /// [keyForValue] returns the key in the map that should be associated with | 425 /// [keyForValue] returns the key in the map that should be associated with |
| 421 /// the given value. The set's notion of equality is identical to the equality | 426 /// the given value. The set's notion of equality is identical to the equality |
| 422 /// of the return values of [keyForValue]. | 427 /// of the return values of [keyForValue]. |
| 423 MapValueSet(Map<K, V> base, K keyForValue(V value)) | 428 MapValueSet(Map<K, V> base, K keyForValue(V value)) |
| 424 : _baseMap = base, | 429 : _baseMap = base, |
| 425 _keyForValue = keyForValue; | 430 _keyForValue = keyForValue; |
| 426 | 431 |
| 427 Iterable<V> get _base => _baseMap.values; | 432 Iterable<V> get _base => _baseMap.values; |
| 428 | 433 |
| 429 bool contains(Object element) { | 434 bool contains(Object element) { |
| 430 if (element != null && element is! V) return false; | 435 if (element != null && element is! V) return false; |
| 431 return _baseMap.containsKey(_keyForValue(element)); | 436 var key = _keyForValue(element as V); |
| 437 |
| 438 return _baseMap.containsKey(key); |
| 432 } | 439 } |
| 433 | 440 |
| 434 bool get isEmpty => _baseMap.isEmpty; | 441 bool get isEmpty => _baseMap.isEmpty; |
| 435 | 442 |
| 436 bool get isNotEmpty => _baseMap.isNotEmpty; | 443 bool get isNotEmpty => _baseMap.isNotEmpty; |
| 437 | 444 |
| 438 int get length => _baseMap.length; | 445 int get length => _baseMap.length; |
| 439 | 446 |
| 440 String toString() => toSet().toString(); | 447 String toString() => toSet().toString(); |
| 441 | 448 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 467 | 474 |
| 468 /// Returns a new set which is the intersection between [this] and [other]. | 475 /// Returns a new set which is the intersection between [this] and [other]. |
| 469 /// | 476 /// |
| 470 /// That is, the returned set contains all the elements of this [Set] that are | 477 /// That is, the returned set contains all the elements of this [Set] that are |
| 471 /// also elements of [other] according to `other.contains`. | 478 /// also elements of [other] according to `other.contains`. |
| 472 /// | 479 /// |
| 473 /// Note that the returned set will use the default equality operation, which | 480 /// Note that the returned set will use the default equality operation, which |
| 474 /// may be different than the equality operation [this] uses. | 481 /// may be different than the equality operation [this] uses. |
| 475 Set<V> intersection(Set<Object> other) => where(other.contains).toSet(); | 482 Set<V> intersection(Set<Object> other) => where(other.contains).toSet(); |
| 476 | 483 |
| 477 V lookup(Object element) => _baseMap[_keyForValue(element)]; | 484 V lookup(Object element) { |
| 485 if (element != null && element is! V) return null; |
| 486 var key = _keyForValue(element as V); |
| 478 | 487 |
| 479 bool remove(Object value) { | 488 return _baseMap[key]; |
| 480 if (value != null && value is! V) return false; | 489 } |
| 481 var key = _keyForValue(value); | 490 |
| 491 bool remove(Object element) { |
| 492 if (element != null && element is! V) return false; |
| 493 var key = _keyForValue(element as V); |
| 494 |
| 482 if (!_baseMap.containsKey(key)) return false; | 495 if (!_baseMap.containsKey(key)) return false; |
| 483 _baseMap.remove(key); | 496 _baseMap.remove(key); |
| 484 return true; | 497 return true; |
| 485 } | 498 } |
| 486 | 499 |
| 487 void removeAll(Iterable<Object> elements) => elements.forEach(remove); | 500 void removeAll(Iterable<Object> elements) => elements.forEach(remove); |
| 488 | 501 |
| 489 void removeWhere(bool test(V element)) { | 502 void removeWhere(bool test(V element)) { |
| 490 var toRemove = []; | 503 var toRemove = []; |
| 491 _baseMap.forEach((key, value) { | 504 _baseMap.forEach((key, value) { |
| 492 if (test(value)) toRemove.add(key); | 505 if (test(value)) toRemove.add(key); |
| 493 }); | 506 }); |
| 494 toRemove.forEach(_baseMap.remove); | 507 toRemove.forEach(_baseMap.remove); |
| 495 } | 508 } |
| 496 | 509 |
| 497 void retainAll(Iterable<Object> elements) { | 510 void retainAll(Iterable<Object> elements) { |
| 498 var valuesToRetain = new Set<V>.identity(); | 511 var valuesToRetain = new Set<V>.identity(); |
| 499 for (var element in elements) { | 512 for (var element in elements) { |
| 500 if (element != null && element is! V) continue; | 513 if (element != null && element is! V) continue; |
| 501 var key = _keyForValue(element); | 514 var key = _keyForValue(element as V); |
| 515 |
| 502 if (!_baseMap.containsKey(key)) continue; | 516 if (!_baseMap.containsKey(key)) continue; |
| 503 valuesToRetain.add(_baseMap[key]); | 517 valuesToRetain.add(_baseMap[key]); |
| 504 } | 518 } |
| 505 | 519 |
| 506 var keysToRemove = []; | 520 var keysToRemove = []; |
| 507 _baseMap.forEach((k, v) { | 521 _baseMap.forEach((k, v) { |
| 508 if (!valuesToRetain.contains(v)) keysToRemove.add(k); | 522 if (!valuesToRetain.contains(v)) keysToRemove.add(k); |
| 509 }); | 523 }); |
| 510 keysToRemove.forEach(_baseMap.remove); | 524 keysToRemove.forEach(_baseMap.remove); |
| 511 } | 525 } |
| 512 | 526 |
| 513 void retainWhere(bool test(V element)) => | 527 void retainWhere(bool test(V element)) => |
| 514 removeWhere((element) => !test(element)); | 528 removeWhere((element) => !test(element)); |
| 515 | 529 |
| 516 /// Returns a new set which contains all the elements of [this] and [other]. | 530 /// Returns a new set which contains all the elements of [this] and [other]. |
| 517 /// | 531 /// |
| 518 /// That is, the returned set contains all the elements of this [Set] and all | 532 /// That is, the returned set contains all the elements of this [Set] and all |
| 519 /// the elements of [other]. | 533 /// the elements of [other]. |
| 520 /// | 534 /// |
| 521 /// Note that the returned set will use the default equality operation, which | 535 /// Note that the returned set will use the default equality operation, which |
| 522 /// may be different than the equality operation [this] uses. | 536 /// may be different than the equality operation [this] uses. |
| 523 Set<V> union(Set<V> other) => toSet()..addAll(other); | 537 Set<V> union(Set<V> other) => toSet()..addAll(other); |
| 524 } | 538 } |
| OLD | NEW |