From 141d83af3d7586ae9d27de610fd426071c98e5d3 Mon Sep 17 00:00:00 2001 From: Graciliano Monteiro Passos Date: Fri, 7 Jun 2024 19:46:31 -0300 Subject: [PATCH] `CanonicalizedMap`: added constructor `fromEntries`. (#347) --- CHANGELOG.md | 1 + lib/src/canonicalized_map.dart | 17 +++++++++++++++++ test/canonicalized_map_test.dart | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e38e1a8..31ac61e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Shuffle `IterableExtension.sample` results. - Fix `mergeSort` when the runtime iterable generic is a subtype of the static generic. +- `CanonicalizedMap`: added constructor `fromEntries`. - Require Dart `^3.1.0` - Mark "mixin" classes as `mixin`. diff --git a/lib/src/canonicalized_map.dart b/lib/src/canonicalized_map.dart index 8490924..4103843 100644 --- a/lib/src/canonicalized_map.dart +++ b/lib/src/canonicalized_map.dart @@ -46,6 +46,23 @@ class CanonicalizedMap implements Map { addAll(other); } + /// Creates a canonicalized map that is initialized with the key/value pairs + /// of [entries]. + /// + /// The [canonicalize] function should return the canonical value for the + /// given key. Keys with the same canonical value are considered equivalent. + /// + /// The [isValidKey] function is called before calling [canonicalize] for + /// methods that take arbitrary objects. It can be used to filter out keys + /// that can't be canonicalized. + CanonicalizedMap.fromEntries( + Iterable> entries, C Function(K key) canonicalize, + {bool Function(K key)? isValidKey}) + : _canonicalize = canonicalize, + _isValidKeyFn = isValidKey { + addEntries(entries); + } + CanonicalizedMap._( this._canonicalize, this._isValidKeyFn, Map> base) { _base.addAll(base); diff --git a/test/canonicalized_map_test.dart b/test/canonicalized_map_test.dart index 9ae4657..aadb734 100644 --- a/test/canonicalized_map_test.dart +++ b/test/canonicalized_map_test.dart @@ -205,6 +205,24 @@ void main() { }); }); + group('CanonicalizedMap.fromEntries', () { + test('canonicalizes its keys', () { + var map = CanonicalizedMap.fromEntries( + {'1': 'value 1', '2': 'value 2', '3': 'value 3'}.entries, int.parse); + expect(map['01'], equals('value 1')); + expect(map['02'], equals('value 2')); + expect(map['03'], equals('value 3')); + }); + + test('uses the final value for collisions', () { + var map = CanonicalizedMap.fromEntries( + {'1': 'value 1', '01': 'value 2', '001': 'value 3'}.entries, + int.parse); + expect(map.length, equals(1)); + expect(map['0001'], equals('value 3')); + }); + }); + group('CanonicalizedMap.toMapOfCanonicalKeys', () { test('convert to a `Map`', () { var map = CanonicalizedMap.from(