Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: pkg/collection/lib/src/canonicalized_map.dart

Issue 350183010: Add a CanonicalizedMap class to pkg/collection. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/collection/lib/src/canonicalized_map.dart
diff --git a/pkg/collection/lib/src/canonicalized_map.dart b/pkg/collection/lib/src/canonicalized_map.dart
new file mode 100644
index 0000000000000000000000000000000000000000..6661dfba7e64efb50235ea357024022db7d0bb3e
--- /dev/null
+++ b/pkg/collection/lib/src/canonicalized_map.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2014, 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.
+
+library dart.pkg.collection.canonicalized_map;
+
+import 'utils.dart';
+
+/**
+ * A map whose keys are converted to canonical values of type `C`.
+ *
+ * This is useful for using case-insensitive String keys, for example. It's more
+ * efficient than a [LinkedHashMap] with a custom equality operator because it
+ * only canonicalizes each once, rather than doing so for each comparison.
Lasse Reichstein Nielsen 2014/07/01 09:18:15 each once -> each key once
nweiz 2014/07/01 21:21:44 Done.
+ */
Lasse Reichstein Nielsen 2014/07/01 09:18:15 Document whether the Map allows null as a key (afa
nweiz 2014/07/01 21:21:44 Done.
+class CanonicalizedMap<C, K, V> implements Map<K, V> {
+ final Function _canonicalize;
+
+ final _base = new Map<C, Pair<K, V>>();
+
+ /**
+ * Creates an empty canonicalized map.
+ *
+ * The [canonicalize] function should return the canonical value for the given
+ * key. Keys with the same canonical value are considered equivalent.
+ */
+ CanonicalizedMap(C canonicalize(K key))
+ : _canonicalize = canonicalize;
+
+ /**
+ * Creates a canonicalized map that is initialized with the key/value pairs of
+ * [other].
+ *
+ * The [canonicalize] function should return the canonical value for the given
+ * key. Keys with the same canonical value are considered equivalent.
+ */
+ CanonicalizedMap.from(Map<K, V> other, C canonicalize(K key))
+ : _canonicalize = canonicalize {
+ addAll(other);
+ }
+
+ V operator [](Object key) {
+ if (key != null && key is! K) return null;
+ var pair = _base[_canonicalize(key)];
+ return pair == null ? null : pair.last;
+ }
+
+ void operator []=(K key, V value) {
+ _base[_canonicalize(key)] = new Pair(key, value);
+ }
+
+ void addAll(Map<K, V> other) {
+ other.forEach((key, value) => this[key] = value);
+ }
+
+ void clear() => _base.clear();
Lasse Reichstein Nielsen 2014/07/01 09:18:15 I'd prefer "{...}" to "=>" for a void function.
nweiz 2014/07/01 21:21:44 Done.
+
+ bool containsKey(Object key) {
+ if (key != null && key is! K) return null;
+ return _base.containsKey(_canonicalize(key));
+ }
+
+ bool containsValue(Object value) =>
+ _base.values.any((pair) => pair.last == value);
+
+ void forEach(void f(K key, V value)) {
+ _base.forEach((key, pair) => f(pair.first, pair.last));
+ }
+
+ bool get isEmpty => _base.isEmpty;
+
+ bool get isNotEmpty => _base.isNotEmpty;
+
+ Iterable<K> get keys => _base.values.map((pair) => pair.first);
+
+ int get length => _base.length;
+
+ V putIfAbsent(K key, V ifAbsent()) {
+ return _base.putIfAbsent(_canonicalize(key),
+ () => new Pair(key, ifAbsent())).last;
+ }
+
+ V remove(Object key) {
+ if (key != null && key is! K) return null;
+ var pair = _base.remove(_canonicalize(key));
+ return pair == null ? null : pair.last;
+ }
+
+ Iterable<K> get values => _base.values.map((pair) => pair.last);
+
+ String toString() => "{" +
+ _base.values.map((pair) => "${pair.first}: ${pair.last}").join(", ") +
+ "}";
Lasse Reichstein Nielsen 2014/07/01 09:18:15 Just use: String toString() => Maps.mapToString
nweiz 2014/07/01 21:21:44 Done.
+}

Powered by Google App Engine
This is Rietveld 408576698