Chromium Code Reviews| 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 /** | 5 /** |
| 6 * This contains extra functions and classes useful for implementing | 6 * This contains extra functions and classes useful for implementing |
| 7 * serialiation. Some or all of these will be removed once the functionality is | 7 * serialiation. Some or all of these will be removed once the functionality is |
| 8 * available in the core library. | 8 * available in the core library. |
| 9 */ | 9 */ |
| 10 library serialization_helpers; | 10 library serialization_helpers; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 Iterable append(Iterable a, Iterable b) { | 23 Iterable append(Iterable a, Iterable b) { |
| 24 if (a == null) { | 24 if (a == null) { |
| 25 return (b == null) ? [] : new List.from(b); | 25 return (b == null) ? [] : new List.from(b); |
| 26 } | 26 } |
| 27 if (b == null) return new List.from(a); | 27 if (b == null) return new List.from(a); |
| 28 var result = new List.from(a); | 28 var result = new List.from(a); |
| 29 result.addAll(b); | 29 result.addAll(b); |
| 30 return result; | 30 return result; |
| 31 } | 31 } |
| 32 | 32 |
| 33 /** | |
| 34 * Return a sorted version of [anIterable], using the default sort criterion. | |
| 35 * Always returns a List, regardless of the type of [anIterable]. | |
| 36 */ | |
| 37 List sorted(anIterable) { | |
| 38 var result = new List.from(anIterable); | |
| 39 result.sort(); | |
| 40 return result; | |
| 41 } | |
| 42 | |
| 43 /** Helper function for PrimitiveRule to tell which objects it applies to. */ | 33 /** Helper function for PrimitiveRule to tell which objects it applies to. */ |
| 44 bool isPrimitive(object) { | 34 bool isPrimitive(object) { |
| 45 return identical(object, null) || object is num || object is String || | 35 return identical(object, null) || object is num || object is String || |
| 46 identical(object, true) || identical(object, false); | 36 identical(object, true) || identical(object, false); |
| 47 } | 37 } |
| 48 | 38 |
| 49 /** | 39 /** |
| 50 * Be able to iterate polymorphically between List-like and Map-like things. | 40 * Given either an Iterable or a Map, return a map. For a Map just return it. |
| 41 * For an iterable, return a Map from the index to the value at that index. | |
| 42 * | |
| 43 * Used to iterate polymorphically between List-like and Map-like things. | |
| 51 * For example, keysAndValues(["a", "b", "c"]).forEach((key, value) => ...); | 44 * For example, keysAndValues(["a", "b", "c"]).forEach((key, value) => ...); |
| 52 * will loop over the key/value pairs 1/"a", 2/"b", 3/"c", as if the argument | 45 * will loop over the key/value pairs 1/"a", 2/"b", 3/"c", as if the argument |
| 53 * was a Map from integer keys to string values. | 46 * was a Map from integer keys to string values. |
| 54 * Only supports forEach() and map() operations because that was all the code | |
| 55 * needed for the moment. | |
| 56 */ | 47 */ |
| 57 MapLikeIterable keysAndValues(x) { | 48 Map keysAndValues(x) { |
| 58 if (x is Map) return new MapLikeIterableForMap(x); | 49 if (x is Map) return x; |
| 59 if (x is Iterable) return new MapLikeIterableForList(x); | 50 if (x is List) return x.asMap(); |
| 51 if (x is Iterable) return x.toList().asMap(); | |
| 60 throw new ArgumentError("Invalid argument"); | 52 throw new ArgumentError("Invalid argument"); |
| 61 } | 53 } |
| 62 | 54 |
| 63 /** | 55 /** |
| 64 * A class for iterating over things as if they were Maps, which primarily | 56 * Lets you iterate polymorphically between |
| 65 * means that forEach() and map() pass two arguments, and map() returns a new | |
| 66 * Map with the same keys as [collection] and values which have been transformed | |
| 67 * by the argument to map(). | |
| 68 */ | |
| 69 abstract class MapLikeIterable { | |
| 70 MapLikeIterable(this.collection); | |
| 71 final collection; | |
| 72 | |
| 73 /** Iterate over the collection, passing both key and value parameters. */ | |
| 74 void forEach(Function f); | |
| 75 | |
| 76 /** | |
| 77 * Return a new collection whose keys are the same as [collection], but whose | |
| 78 * values are the result of applying [f] to the key/value pairs. So, if | |
| 79 * [collection] is a List, it will be the same as the map() method if the | |
| 80 * [key] parameter wasn't passed. | |
| 81 */ | |
| 82 map(Function f) { | |
| 83 var result = copyEmpty(); | |
| 84 forEach((key, value) { | |
| 85 result[key] = f(key, value); | |
| 86 }); | |
| 87 return result; | |
| 88 } | |
| 89 | |
| 90 /** | |
| 91 * Return an empty copy of our collection. Very limited, only knows enough | |
| 92 * to return a Map or List as appropriate. | |
| 93 */ | |
| 94 copyEmpty(); | |
| 95 } | |
| 96 | |
| 97 | |
| 98 | |
| 99 class MapLikeIterableForMap extends MapLikeIterable { | |
| 100 MapLikeIterableForMap(collection) : super(collection); | |
| 101 | |
| 102 void forEach(Function f) { collection.forEach(f);} | |
| 103 Map copyEmpty() => new Map(); | |
| 104 } | |
| 105 | |
| 106 class MapLikeIterableForList extends MapLikeIterable { | |
| 107 MapLikeIterableForList(collection) : super(collection); | |
| 108 | |
| 109 void forEach(f) { | |
| 110 Iterator iterator = collection.iterator; | |
| 111 for (var i = 0; i < collection.length; i++) { | |
| 112 iterator.moveNext(); | |
| 113 f(i, iterator.current); | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 List copyEmpty() => new List(collection.length); | |
| 118 } | |
| 119 | |
| 120 /** | |
| 121 * An inverse of MapLikeIterable. Lets you iterate polymorphically between | |
| 122 * List-like and Map-like things, but making them behave like Lists, instead | 57 * List-like and Map-like things, but making them behave like Lists, instead |
| 123 * of behaving like Maps. | 58 * of behaving like Maps. |
| 124 * So values(["a", "b", "c"]).forEach((value) => ...); | 59 * So values(["a", "b", "c"]).forEach((value) => ...); |
| 125 * will loop over the values "a", "b", "c", as if it were a List of values. | 60 * will loop over the values "a", "b", "c", as if it were a List of values. |
| 126 * Only supports forEach() and map() operations because that was all I needed | 61 * Only supports forEach() and map() operations because that was all I needed |
| 127 * for the moment. | 62 * for the moment. |
| 128 */ | 63 */ |
| 129 values(x) { | 64 values(x) { |
|
kevmoo-old
2013/09/25 20:30:03
return type of Iterable, then?
Alan Knight
2013/09/26 16:39:08
Yes, I suppose so.
| |
| 130 if (x is Iterable) return x; | 65 if (x is Iterable) return x; |
| 131 if (x is Map) return new ListLikeIterable(x); | 66 if (x is Map) return x.values; |
| 132 throw new ArgumentError("Invalid argument"); | |
| 133 } | |
| 134 | |
| 135 mapValues(x, f) { | |
| 136 if (x is Set) return x.map(f).toSet(); | |
| 137 if (x is Iterable) return x.map(f).toList(); | |
| 138 if (x is Map) return new ListLikeIterable(x).map(f); | |
| 139 throw new ArgumentError("Invalid argument"); | 67 throw new ArgumentError("Invalid argument"); |
| 140 } | 68 } |
| 141 | 69 |
| 142 /** | 70 /** |
| 143 * A class for iterating over things as if they were Lists, which primarily | 71 * Iterate over [collection] and return a new collection of the same type |
| 144 * means that forEach passes one argument, and map() returns a new Map | 72 * where each value has been transformed by [f]. For iterables and sets, this |
| 145 * with the same keys as [collection] and values which haev been transformed | 73 * is equivalent to [map]. For a Map, it returns a new Map with the same keys |
| 146 * by the argument to map(). | 74 * and the corresponding values transformed by [f]. |
| 147 */ | 75 */ |
| 148 class ListLikeIterable { | 76 mapValues(collection, Function f) { |
| 149 ListLikeIterable(this.collection); | 77 if (collection is Set) return collection.map(f).toSet(); |
| 150 final Map collection; | 78 if (collection is Iterable) return collection.map(f).toList(); |
| 151 | 79 if (collection is Map) return new Map.fromIterables(collection.keys, |
| 152 /** Iterate over the collection, passing just the value parameters. */ | 80 collection.values.map(f)); |
| 153 forEach(f) { | 81 throw new ArgumentError("Invalid argument"); |
| 154 collection.forEach((key, value) => f(value)); | |
| 155 } | |
| 156 | |
| 157 /** | |
| 158 * Return a new collection whose keys are the same as [collection], but whose | |
| 159 * values are the result of applying [f] to the key/value pairs. So, if | |
| 160 * [collection] is a List, it will be the same as if map() had been called | |
| 161 * directly on [collection]. | |
| 162 */ | |
| 163 map(Function f) { | |
| 164 var result = new Map(); | |
| 165 collection.forEach((key, value) => result[key] = f(value)); | |
| 166 return result; | |
| 167 } | |
| 168 | |
| 169 /** | |
| 170 * Return an iterator that behaves like a List iterator, taking one parameter. | |
| 171 */ | |
| 172 Iterator get iterator => collection.values.iterator; | |
| 173 } | 82 } |
| 174 | 83 |
| 175 /** | 84 /** |
| 176 * This acts as a stand-in for some value that cannot be hashed. We can't | 85 * This acts as a stand-in for some value that cannot be hashed. We can't |
| 177 * just use const Object() because the compiler will fold them together. | 86 * just use const Object() because the compiler will fold them together. |
| 178 */ | 87 */ |
| 179 class _Sentinel { | 88 class _Sentinel { |
| 180 final _wrappedObject; | 89 final _wrappedObject; |
| 181 const _Sentinel(this._wrappedObject); | 90 const _Sentinel(this._wrappedObject); |
| 182 } | 91 } |
| OLD | NEW |