diff --git a/pkgs/collection/CHANGELOG.md b/pkgs/collection/CHANGELOG.md index 021dd937..239efd57 100644 --- a/pkgs/collection/CHANGELOG.md +++ b/pkgs/collection/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.19.1-wip +- Add `IterableMapEntryExtension` for working on `Map` as a list of pairs, using + `Map.entries`. + ## 1.19.1 - Move to `dart-lang/core` monorepo. diff --git a/pkgs/collection/lib/src/iterable_extensions.dart b/pkgs/collection/lib/src/iterable_extensions.dart index e2050062..b05e3fa7 100644 --- a/pkgs/collection/lib/src/iterable_extensions.dart +++ b/pkgs/collection/lib/src/iterable_extensions.dart @@ -914,6 +914,33 @@ extension IterableIterableExtension on Iterable> { }; } +/// Extension on iterables of [MapEntry]. +/// +/// An [Iterable] is obtained using [Map.entries], these extensions +/// make it easy to work on a [Map] as a list of pairs. +extension IterableMapEntryExtension on Iterable> { + /// Creates a new lazy [Iterable] with all elements whose [MapEntry.key] + /// satisfy the predicate [test]. + Iterable> whereKey(bool Function(K) test) => + where((e) => test(e.key)); + + /// Creates a new lazy [Iterable] with all elements whose [MapEntry.value] + /// satisfy the predicate [test]. + Iterable> whereValue(bool Function(V) test) => + where((e) => test(e.value)); + + /// Create an new lazy [Iterable] with [MapEntry.key] from all elements. + Iterable get keys => map((e) => e.key); + + /// Create an new lazy [Iterable] with [MapEntry.value] from all elements. + Iterable get values => map((e) => e.value); + + /// Create a [Map] from all elements. + /// + /// This is a short-hand for [Map.fromEntries]. + Map toMap() => Map.fromEntries(this); +} + /// Extensions that apply to iterables of [Comparable] elements. /// /// These operations can assume that the elements have a natural ordering, diff --git a/pkgs/collection/pubspec.yaml b/pkgs/collection/pubspec.yaml index c1b16334..4e74ac7a 100644 --- a/pkgs/collection/pubspec.yaml +++ b/pkgs/collection/pubspec.yaml @@ -1,5 +1,5 @@ name: collection -version: 1.19.1 +version: 1.19.1-wip description: >- Collections and utilities functions and classes related to collections. repository: https://github.com/dart-lang/core/tree/main/pkgs/collection diff --git a/pkgs/collection/test/extensions_test.dart b/pkgs/collection/test/extensions_test.dart index 9940e1d4..1d7a0ec0 100644 --- a/pkgs/collection/test/extensions_test.dart +++ b/pkgs/collection/test/extensions_test.dart @@ -1122,6 +1122,87 @@ void main() { }); }); }); + group('of MapEntry', () { + group('.whereKey', () { + test('empty', () { + expect({}.entries.whereKey(unreachable), isEmpty); + }); + test('single', () { + expect({'a': 1}.entries.whereKey((k) => k == 'a').toMap(), {'a': 1}); + expect({'a': 1}.entries.whereKey((k) => k == 'b').toMap(), isEmpty); + }); + test('multiple', () { + expect( + {'a': 1, 'b': 2}.entries.whereKey((k) => k == 'a').toMap(), + {'a': 1}, + ); + expect( + {'a': 1, 'b': 2}.entries.whereKey((k) => k == 'b').toMap(), + {'b': 2}, + ); + expect( + {'a': 1, 'b': 2}.entries.whereKey((k) => k != 'c').toMap(), + {'a': 1, 'b': 2}, + ); + }); + }); + group('.whereValue', () { + test('empty', () { + expect({}.entries.whereValue(unreachable), isEmpty); + }); + test('single', () { + expect({'a': 1}.entries.whereValue((v) => v == 1).toMap(), {'a': 1}); + expect({'a': 1}.entries.whereValue((v) => v == 2).toMap(), isEmpty); + }); + test('multiple', () { + expect( + {'a': 1, 'b': 2}.entries.whereValue((v) => v == 1).toMap(), + {'a': 1}, + ); + expect( + {'a': 1, 'b': 2}.entries.whereValue((v) => v == 2).toMap(), + {'b': 2}, + ); + expect( + {'a': 1, 'b': 2}.entries.whereValue((v) => v != 3).toMap(), + {'a': 1, 'b': 2}, + ); + }); + }); + group('.keys', () { + test('empty', () { + expect({}.entries.keys, isEmpty); + }); + test('single', () { + expect({'a': 1}.entries.keys, ['a']); + }); + test('multiple', () { + expect({'a': 1, 'b': 2}.entries.keys, ['a', 'b']); + }); + }); + group('.values', () { + test('empty', () { + expect({}.entries.values, isEmpty); + }); + test('single', () { + expect({'a': 1}.entries.values, [1]); + }); + test('multiple', () { + expect({'a': 1, 'b': 2}.entries.values, [1, 2]); + }); + }); + group('.toMap', () { + test('empty', () { + expect({}.entries.toMap(), {}); + }); + test('single', () { + expect({'a': 1}.entries.toMap(), {'a': 1}); + }); + test('multiple', () { + expect({'a': 1, 'b': 2}.entries.toMap(), {'a': 1, 'b': 2}); + }); + }); + }); group('of comparable', () { group('.min', () { test('empty', () {