| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| /* | |
| * Helper class which implements complex [Map] operations | |
| * in term of basic ones ([Map.getKeys], [Map.operator []], | |
| * [Map.operator []=] and [Map.remove].) Not all methods are | |
| * necessary to implement each particular operation. | |
| */ | |
| class Maps { | |
| static bool containsValue(Map map, value) { | |
| for (final v in map.getValues()) { | |
| if (value == v) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| static bool containsKey(Map map, key) { | |
| for (final k in map.getKeys()) { | |
| if (key == k) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| static putIfAbsent(Map map, key, ifAbsent()) { | |
| if (map.containsKey(key)) { | |
| return map[key]; | |
| } | |
| final v = ifAbsent(); | |
| map[key] = v; | |
| return v; | |
| } | |
| static clear(Map map) { | |
| for (final k in map.getKeys()) { | |
| map.remove(k); | |
| } | |
| } | |
| static forEach(Map map, void f(key, value)) { | |
| for (final k in map.getKeys()) { | |
| f(k, map[k]); | |
| } | |
| } | |
| static Collection getValues(Map map) { | |
| final result = []; | |
| for (final k in map.getKeys()) { | |
| result.add(map[k]); | |
| } | |
| return result; | |
| } | |
| static int length(Map map) => map.getKeys().length; | |
| static bool isEmpty(Map map) => length(map) == 0; | |
| /** | |
| * Returns a string representing the specified map. The returned string | |
| * looks like this: [:'{key0: value0, key1: value1, ... keyN: valueN}':]. | |
| * The value returned by its [toString] method is used to represent each | |
| * key or value. | |
| * | |
| * If the map collection contains a reference to itself, either | |
| * directly as a key or value, or indirectly through other collections | |
| * or maps, the contained reference is rendered as [:'{...}':]. This | |
| * prevents the infinite regress that would otherwise occur. So, for example, | |
| * calling this method on a map whose sole entry maps the string key 'me' | |
| * to a reference to the map would return [:'{me: {...}}':]. | |
| * | |
| * A typical implementation of a map's [toString] method will | |
| * simply return the results of this method applied to the collection. | |
| */ | |
| static String mapToString(Map m) { | |
| var result = new StringBuffer(); | |
| _emitMap(m, result, new List()); | |
| return result.toString(); | |
| } | |
| /** | |
| * Appends a string representing the specified map to the specified | |
| * string buffer. The string is formatted as per [mapToString]. | |
| * The [:visiting:] list contains references to all of the enclosing | |
| * collections and maps (which are currently in the process of being | |
| * emitted into [:result:]). The [:visiting:] parameter allows this method | |
| * to generate a [:'[...]':] or [:'{...}':] where required. In other words, | |
| * it allows this method and [_emitCollection] to identify recursive maps | |
| * and collections. | |
| */ | |
| static void _emitMap(Map m, StringBuffer result, List visiting) { | |
| visiting.add(m); | |
| result.add('{'); | |
| bool first = true; | |
| m.forEach((k, v) { | |
| if (!first) { | |
| result.add(', '); | |
| } | |
| first = false; | |
| Collections._emitObject(k, result, visiting); | |
| result.add(': '); | |
| Collections._emitObject(v, result, visiting); | |
| }); | |
| result.add('}'); | |
| visiting.removeLast(); | |
| } | |
| } |