| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, 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 // Collection<T> supports most of the ES 5 Array methods, but it's missing | |
| 6 // map and reduce. | |
| 7 | |
| 8 // TODO(jmesserly): we might want a version of this that return an iterable, | |
| 9 // however JS, Python and Ruby versions are all eager. | |
| 10 List map(Iterable source, mapper(source)) { | |
| 11 List result = new List(); | |
| 12 if (source is List) { | |
| 13 List list = source; // TODO: shouldn't need this | |
| 14 result.length = list.length; | |
| 15 for (int i = 0; i < list.length; i++) { | |
| 16 result[i] = mapper(list[i]); | |
| 17 } | |
| 18 } else { | |
| 19 for (final item in source) { | |
| 20 result.add(mapper(item)); | |
| 21 } | |
| 22 } | |
| 23 return result; | |
| 24 } | |
| 25 | |
| 26 reduce(Iterable source, callback, [initialValue]) { | |
| 27 final i = source.iterator(); | |
| 28 | |
| 29 var current = initialValue; | |
| 30 if (current == null && i.hasNext()) { | |
| 31 current = i.next(); | |
| 32 } | |
| 33 while (i.hasNext()) { | |
| 34 current = callback(current, i.next()); | |
| 35 } | |
| 36 return current; | |
| 37 } | |
| 38 | |
| 39 List zip(Iterable left, Iterable right, mapper(left, right)) { | |
| 40 List result = new List(); | |
| 41 var x = left.iterator(); | |
| 42 var y = right.iterator(); | |
| 43 while (x.hasNext() && y.hasNext()) { | |
| 44 result.add(mapper(x.next(), y.next())); | |
| 45 } | |
| 46 if (x.hasNext() || y.hasNext()) { | |
| 47 throw new IllegalArgumentException(); | |
| 48 } | |
| 49 return result; | |
| 50 } | |
| 51 | |
| 52 /** Sorts the map by the key. */ | |
| 53 List orderValuesByKeys(Map map) { | |
| 54 // TODO(jmesserly): it'd be nice to have SortedMap in corelib. | |
| 55 List keys = map.getKeys(); | |
| 56 keys.sort((x, y) => x.compareTo(y)); | |
| 57 final values = []; | |
| 58 for (var k in keys) { | |
| 59 values.add(map[k]); | |
| 60 } | |
| 61 return values; | |
| 62 } | |
| 63 | |
| 64 /** | |
| 65 * A [FixedCollection] is a collection of [length] items all of which have the | |
| 66 * identical [value] | |
| 67 */ | |
| 68 class FixedCollection<E> implements Collection<E> { | |
| 69 final E value; | |
| 70 final int length; | |
| 71 const FixedCollection(this.value, this.length); | |
| 72 | |
| 73 Iterator<E> iterator() => new FixedIterator<E>(value, length); | |
| 74 void forEach(void f(E element)) { Collections.forEach(this, f); } | |
| 75 Collection map(f(E element)) => Collections.map(this, new List(), f); | |
| 76 Collection<E> filter(bool f(E element)) { | |
| 77 return Collections.filter(this, new List<E>(), f); | |
| 78 } | |
| 79 bool every(bool f(E element)) => Collections.every(this, f); | |
| 80 bool some(bool f(E element)) => Collections.some(this, f); | |
| 81 bool isEmpty() => length == 0; | |
| 82 } | |
| 83 | |
| 84 class FixedIterator<E> implements Iterator<E> { | |
| 85 final E value; | |
| 86 final int length; | |
| 87 int _index = 0; | |
| 88 FixedIterator(this.value, this.length); | |
| 89 | |
| 90 bool hasNext() => _index < length; | |
| 91 E next() { | |
| 92 _index++; | |
| 93 return value; | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 // Color constants used for generating messages. | |
| 98 String _GREEN_COLOR = '\u001b[32m'; | |
| 99 String _RED_COLOR = '\u001b[31m'; | |
| 100 String _MAGENTA_COLOR = '\u001b[35m'; | |
| 101 String _NO_COLOR = '\u001b[0m'; | |
| 102 | |
| 103 | |
| 104 /** | |
| 105 * An implementation detail of [CopyOnWriteMap]. Essentially just | |
| 106 * [HashMapImplementation] plus an additional [shared] field. | |
| 107 */ | |
| 108 class _SharedBackingMap<K, V> extends HashMapImplementation<K, V> { | |
| 109 /** | |
| 110 * The number of [CopyOnWriteMap] instances sharing this excluding the | |
| 111 * original, i.e. it is safe to write iff `shared == 0`; | |
| 112 */ | |
| 113 int shared = 0; | |
| 114 _SharedBackingMap(); | |
| 115 factory _SharedBackingMap.from(Map<K, V> other) { | |
| 116 final result = new _SharedBackingMap<K, V>(); | |
| 117 other.forEach((K k, V v) { result[k] = v; }); | |
| 118 return result; | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 /** A copy-on-write [Map] implementation. */ | |
| 123 // TODO(jmesserly): A persistent tree-based implementation of Map would be much | |
| 124 // nicer. This is just a quick hack to get things working. | |
| 125 class CopyOnWriteMap<K extends Hashable, V> implements HashMap<K, V> { | |
| 126 _SharedBackingMap<K, V> _map; | |
| 127 | |
| 128 CopyOnWriteMap(): _map = new _SharedBackingMap<K, V>(); | |
| 129 CopyOnWriteMap._wrap(this._map); | |
| 130 factory CopyOnWriteMap.from(Map<K, V> other) { | |
| 131 if (other is CopyOnWriteMap<K, V>) { | |
| 132 return other.dynamic.clone(); | |
| 133 } | |
| 134 return new CopyOnWriteMap<K, V>._wrap( | |
| 135 new _SharedBackingMap<K, V>.from(other)); | |
| 136 } | |
| 137 | |
| 138 CopyOnWriteMap<K, V> clone() { | |
| 139 _map.shared++; | |
| 140 return new CopyOnWriteMap<K, V>._wrap(_map); | |
| 141 } | |
| 142 | |
| 143 void _ensureWritable() { | |
| 144 if (_map.shared > 0) { | |
| 145 _map.shared--; | |
| 146 _map = new _SharedBackingMap<K, V>.from(_map); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 void operator []=(K key, V value) { | |
| 151 _ensureWritable(); | |
| 152 _map[key] = value; | |
| 153 } | |
| 154 | |
| 155 V putIfAbsent(K key, V ifAbsent()) { | |
| 156 _ensureWritable(); | |
| 157 return _map.putIfAbsent(key, ifAbsent); | |
| 158 } | |
| 159 | |
| 160 void clear() { | |
| 161 _ensureWritable(); | |
| 162 _map.clear(); | |
| 163 } | |
| 164 | |
| 165 V remove(K key) { | |
| 166 _ensureWritable(); | |
| 167 return _map.remove(key); | |
| 168 } | |
| 169 | |
| 170 // Forwarding methods: | |
| 171 V operator [](K key) => _map[key]; | |
| 172 bool isEmpty() => _map.isEmpty(); | |
| 173 int get length() => _map.length; | |
| 174 void forEach(void f(K key, V value)) => _map.forEach(f); | |
| 175 Collection<K> getKeys() => _map.getKeys(); | |
| 176 Collection<V> getValues() => _map.getValues(); | |
| 177 bool containsKey(K key) => _map.containsKey(key); | |
| 178 bool containsValue(V value) => _map.containsValue(value); | |
| 179 } | |
| OLD | NEW |