Line data Source code
1 : // Copyright (c) 2017, 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 : import 'dart:collection';
6 :
7 : import 'combined_iterable.dart';
8 :
9 : /// Returns a new map that represents maps flattened into a single map.
10 : ///
11 : /// All methods and accessors treat the new map as-if it were a single
12 : /// concatenated map, but the underlying implementation is based on lazily
13 : /// accessing individual map instances. In the occasion where a key occurs in
14 : /// multiple maps the first value is returned.
15 : ///
16 : /// The resulting map has an index operator (`[]`) and `length` property that
17 : /// are both `O(maps)`, rather than `O(1)`, and the map is unmodifiable - but
18 : /// underlying changes to these maps are still accessible from the resulting
19 : /// map.
20 : class CombinedMapView<K, V> extends UnmodifiableMapBase<K, V> {
21 : final Iterable<Map<K, V>> _maps;
22 :
23 : /// Create a new combined view into multiple maps.
24 : ///
25 : /// The iterable is accessed lazily so it should be collection type like
26 : /// [List] or [Set] rather than a lazy iterable produced by `map()` et al.
27 0 : CombinedMapView(this._maps);
28 :
29 : V operator [](Object key) {
30 0 : for (var map in _maps) {
31 : // Avoid two hash lookups on a positive hit.
32 0 : var value = map[key];
33 0 : if (value != null || map.containsKey(value)) {
34 : return value;
35 : }
36 : }
37 : return null;
38 : }
39 :
40 : /// The keys of [this].
41 : ///
42 : /// The returned iterable has efficient `length` and `contains` operations,
43 : /// based on [length] and [containsKey] of the individual maps.
44 : ///
45 : /// The order of iteration is defined by the individual `Map` implementations,
46 : /// but must be consistent between changes to the maps.
47 : ///
48 : /// Unlike most [Map] implementations, modifying an individual map while
49 : /// iterating the keys will _sometimes_ throw. This behavior may change in
50 : /// the future.
51 0 : Iterable<K> get keys => new CombinedIterableView<K>(_maps.map((m) => m.keys));
52 : }
|