From ddcad5bbd77e5dad8da2d292c3974116b542910d Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Fri, 2 Aug 2024 20:08:37 +0300 Subject: [PATCH 01/11] issue-335 countFrequency method added --- lib/src/iterable_extensions.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index e205006..f3f6304 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart @@ -601,6 +601,19 @@ extension IterableExtension on Iterable { yield slice; } } + + /// Returns a map where the keys are the unique elements of the iterable + /// and the values are the counts of those elements. + /// + /// for example, ['a', 'b', 'b', 'c', 'c', 'c'].countFrequency() + /// returns {'a': 1, 'b': 2, 'c': 3}. will it works? + Map countFrequency() { + var frequencyMap = {}; + for (var item in this) { + frequencyMap[item] = (frequencyMap[item] ?? 0) + 1; + } + return frequencyMap; + } } /// Extensions that apply to iterables with a nullable element type. From c2a7133865c7c5c922099458b46bfd660ee5d6bc Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Fri, 2 Aug 2024 20:09:03 +0300 Subject: [PATCH 02/11] issue-335 countFrequency tests added --- test/extensions_test.dart | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/test/extensions_test.dart b/test/extensions_test.dart index 9940e1d..9b5cd0c 100644 --- a/test/extensions_test.dart +++ b/test/extensions_test.dart @@ -2,6 +2,7 @@ // 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. +import 'dart:collection'; import 'dart:math' show Random, pow; import 'package:collection/collection.dart'; @@ -1352,6 +1353,84 @@ void main() { expect(l3.toList(), [4, 5]); }); }); + group('FrequencyCounter tests', () { + test('should return correct frequency map for List of integers', () { + var list = [1, 2, 2, 3, 3, 3]; + var frequencyMap = list.countFrequency(); + expect(frequencyMap, {1: 1, 2: 2, 3: 3}); + }); + + test('should return correct frequency map for List of strings', () { + var list = ['a', 'b', 'b', 'c', 'c', 'c']; + var frequencyMap = list.countFrequency(); + expect(frequencyMap, {'a': 1, 'b': 2, 'c': 3}); + }); + + test('should handle empty List', () { + var list = []; + var frequencyMap = list.countFrequency(); + expect(frequencyMap, {}); + }); + + test('should handle single element List', () { + var list = [42]; + var frequencyMap = list.countFrequency(); + expect(frequencyMap, {42: 1}); + }); + + test('should return correct frequency map for Set of integers', () { + // ignore: equal_elements_in_set + var set = {1, 2, 2, 3, 3, 3}; + var frequencyMap = set.countFrequency(); + expect(frequencyMap, {1: 1, 2: 1, 3: 1}); + }); + + test('should return correct frequency map for Set of strings', () { + // ignore: equal_elements_in_set + var set = {'a', 'b', 'b', 'c', 'c', 'c'}; + var frequencyMap = set.countFrequency(); + expect(frequencyMap, {'a': 1, 'b': 1, 'c': 1}); + }); + + test('should handle empty Set', () { + var set = {}; + var frequencyMap = set.countFrequency(); + expect(frequencyMap, {}); + }); + + test('should handle single element Set', () { + var set = {42}; + var frequencyMap = set.countFrequency(); + expect(frequencyMap, {42: 1}); + }); + + test('should return correct frequency map for Queue of integers', () { + var queue = Queue(); + queue.addAll([1, 2, 2, 3, 3, 3]); + var frequencyMap = queue.countFrequency(); + expect(frequencyMap, {1: 1, 2: 2, 3: 3}); + }); + + test('should return correct frequency map for Queue of strings', () { + var queue = Queue(); + queue.addAll(['a', 'b', 'b', 'c', 'c', 'c']); + var frequencyMap = queue.countFrequency(); + expect(frequencyMap, {'a': 1, 'b': 2, 'c': 3}); + }); + + test('should handle empty Queue', () { + var queue = Queue(); + var frequencyMap = queue.countFrequency(); + expect(frequencyMap, {}); + }); + + test('should handle single element Queue', () { + var queue = Queue(); + queue.add(42); + var frequencyMap = queue.countFrequency(); + expect(frequencyMap, {42: 1}); + }); + }); }); group('Comparator', () { From 0c833d85a7ec68c57b85f78fd4cfbada21e4c239 Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Fri, 2 Aug 2024 20:15:46 +0300 Subject: [PATCH 03/11] issue-335 countFrequency comments edited --- lib/src/iterable_extensions.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index f3f6304..5b80ade 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart @@ -606,7 +606,7 @@ extension IterableExtension on Iterable { /// and the values are the counts of those elements. /// /// for example, ['a', 'b', 'b', 'c', 'c', 'c'].countFrequency() - /// returns {'a': 1, 'b': 2, 'c': 3}. will it works? + /// returns {'a': 1, 'b': 2, 'c': 3}. Map countFrequency() { var frequencyMap = {}; for (var item in this) { From b444e375cc451d201ffd37a20162ce94871bef69 Mon Sep 17 00:00:00 2001 From: Pavel Kriuchkov <57821178+pvlKryu@users.noreply.github.com> Date: Tue, 3 Sep 2024 04:25:06 +1000 Subject: [PATCH 04/11] Update lib/src/iterable_extensions.dart Co-authored-by: Mateus Felipe C. C. Pinto --- lib/src/iterable_extensions.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index 5b80ade..49ef848 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart @@ -605,8 +605,8 @@ extension IterableExtension on Iterable { /// Returns a map where the keys are the unique elements of the iterable /// and the values are the counts of those elements. /// - /// for example, ['a', 'b', 'b', 'c', 'c', 'c'].countFrequency() - /// returns {'a': 1, 'b': 2, 'c': 3}. + /// For example, `['a', 'b', 'b', 'c', 'c', 'c'].countFrequency()` + /// returns `{'a': 1, 'b': 2, 'c': 3}`. Map countFrequency() { var frequencyMap = {}; for (var item in this) { From 1fe3d16334aae6fe0b0ea46f7b265e4d39bd8f3a Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Sun, 29 Sep 2024 13:30:49 +0300 Subject: [PATCH 05/11] issue-335 converted countFrequency to getter --- lib/src/iterable_extensions.dart | 2 +- test/extensions_test.dart | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index 5b80ade..4631909 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart @@ -607,7 +607,7 @@ extension IterableExtension on Iterable { /// /// for example, ['a', 'b', 'b', 'c', 'c', 'c'].countFrequency() /// returns {'a': 1, 'b': 2, 'c': 3}. - Map countFrequency() { + Map get frequencies { var frequencyMap = {}; for (var item in this) { frequencyMap[item] = (frequencyMap[item] ?? 0) + 1; diff --git a/test/extensions_test.dart b/test/extensions_test.dart index 9b5cd0c..83ffb0f 100644 --- a/test/extensions_test.dart +++ b/test/extensions_test.dart @@ -1353,81 +1353,81 @@ void main() { expect(l3.toList(), [4, 5]); }); }); - group('FrequencyCounter tests', () { + group('get frequencies tests', () { test('should return correct frequency map for List of integers', () { var list = [1, 2, 2, 3, 3, 3]; - var frequencyMap = list.countFrequency(); + var frequencyMap = list.frequencies; expect(frequencyMap, {1: 1, 2: 2, 3: 3}); }); test('should return correct frequency map for List of strings', () { var list = ['a', 'b', 'b', 'c', 'c', 'c']; - var frequencyMap = list.countFrequency(); + var frequencyMap = list.frequencies; expect(frequencyMap, {'a': 1, 'b': 2, 'c': 3}); }); test('should handle empty List', () { var list = []; - var frequencyMap = list.countFrequency(); + var frequencyMap = list.frequencies; expect(frequencyMap, {}); }); test('should handle single element List', () { var list = [42]; - var frequencyMap = list.countFrequency(); + var frequencyMap = list.frequencies; expect(frequencyMap, {42: 1}); }); test('should return correct frequency map for Set of integers', () { // ignore: equal_elements_in_set var set = {1, 2, 2, 3, 3, 3}; - var frequencyMap = set.countFrequency(); + var frequencyMap = set.frequencies; expect(frequencyMap, {1: 1, 2: 1, 3: 1}); }); test('should return correct frequency map for Set of strings', () { // ignore: equal_elements_in_set var set = {'a', 'b', 'b', 'c', 'c', 'c'}; - var frequencyMap = set.countFrequency(); + var frequencyMap = set.frequencies; expect(frequencyMap, {'a': 1, 'b': 1, 'c': 1}); }); test('should handle empty Set', () { var set = {}; - var frequencyMap = set.countFrequency(); + var frequencyMap = set.frequencies; expect(frequencyMap, {}); }); test('should handle single element Set', () { var set = {42}; - var frequencyMap = set.countFrequency(); + var frequencyMap = set.frequencies; expect(frequencyMap, {42: 1}); }); test('should return correct frequency map for Queue of integers', () { var queue = Queue(); queue.addAll([1, 2, 2, 3, 3, 3]); - var frequencyMap = queue.countFrequency(); + var frequencyMap = queue.frequencies; expect(frequencyMap, {1: 1, 2: 2, 3: 3}); }); test('should return correct frequency map for Queue of strings', () { var queue = Queue(); queue.addAll(['a', 'b', 'b', 'c', 'c', 'c']); - var frequencyMap = queue.countFrequency(); + var frequencyMap = queue.frequencies; expect(frequencyMap, {'a': 1, 'b': 2, 'c': 3}); }); test('should handle empty Queue', () { var queue = Queue(); - var frequencyMap = queue.countFrequency(); + var frequencyMap = queue.frequencies; expect(frequencyMap, {}); }); test('should handle single element Queue', () { var queue = Queue(); queue.add(42); - var frequencyMap = queue.countFrequency(); + var frequencyMap = queue.frequencies; expect(frequencyMap, {42: 1}); }); }); From 8acd858c4734ba6a06737756f065868ebc5108d3 Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Sun, 29 Sep 2024 13:52:42 +0300 Subject: [PATCH 06/11] issue-335 avoided two lookups per item --- lib/src/iterable_extensions.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index 23d2ab7..91816e9 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart @@ -597,12 +597,15 @@ extension IterableExtension on Iterable { /// for example, ['a', 'b', 'b', 'c', 'c', 'c'].frequencies; /// returns {'a': 1, 'b': 2, 'c': 3}. Map get frequencies { - var frequencyMap = {}; + final frequencyMap = {}; for (var item in this) { - frequencyMap[item] = (frequencyMap[item] ?? 0) + 1; + frequencyMap.update(item, _increment, ifAbsent: _one); } return frequencyMap; } + + static int _increment(int value) => value + 1; + static int _one() => 1; } /// Extensions that apply to iterables with a nullable element type. From facd926cad7d2831bd33d170c97783b3adfaa710 Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Sun, 29 Sep 2024 13:53:43 +0300 Subject: [PATCH 07/11] Revert "issue-335 converted countFrequency to getter" This reverts commit 1fe3d16334aae6fe0b0ea46f7b265e4d39bd8f3a. --- test/extensions_test.dart | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/extensions_test.dart b/test/extensions_test.dart index 83ffb0f..9b5cd0c 100644 --- a/test/extensions_test.dart +++ b/test/extensions_test.dart @@ -1353,81 +1353,81 @@ void main() { expect(l3.toList(), [4, 5]); }); }); - group('get frequencies tests', () { + group('FrequencyCounter tests', () { test('should return correct frequency map for List of integers', () { var list = [1, 2, 2, 3, 3, 3]; - var frequencyMap = list.frequencies; + var frequencyMap = list.countFrequency(); expect(frequencyMap, {1: 1, 2: 2, 3: 3}); }); test('should return correct frequency map for List of strings', () { var list = ['a', 'b', 'b', 'c', 'c', 'c']; - var frequencyMap = list.frequencies; + var frequencyMap = list.countFrequency(); expect(frequencyMap, {'a': 1, 'b': 2, 'c': 3}); }); test('should handle empty List', () { var list = []; - var frequencyMap = list.frequencies; + var frequencyMap = list.countFrequency(); expect(frequencyMap, {}); }); test('should handle single element List', () { var list = [42]; - var frequencyMap = list.frequencies; + var frequencyMap = list.countFrequency(); expect(frequencyMap, {42: 1}); }); test('should return correct frequency map for Set of integers', () { // ignore: equal_elements_in_set var set = {1, 2, 2, 3, 3, 3}; - var frequencyMap = set.frequencies; + var frequencyMap = set.countFrequency(); expect(frequencyMap, {1: 1, 2: 1, 3: 1}); }); test('should return correct frequency map for Set of strings', () { // ignore: equal_elements_in_set var set = {'a', 'b', 'b', 'c', 'c', 'c'}; - var frequencyMap = set.frequencies; + var frequencyMap = set.countFrequency(); expect(frequencyMap, {'a': 1, 'b': 1, 'c': 1}); }); test('should handle empty Set', () { var set = {}; - var frequencyMap = set.frequencies; + var frequencyMap = set.countFrequency(); expect(frequencyMap, {}); }); test('should handle single element Set', () { var set = {42}; - var frequencyMap = set.frequencies; + var frequencyMap = set.countFrequency(); expect(frequencyMap, {42: 1}); }); test('should return correct frequency map for Queue of integers', () { var queue = Queue(); queue.addAll([1, 2, 2, 3, 3, 3]); - var frequencyMap = queue.frequencies; + var frequencyMap = queue.countFrequency(); expect(frequencyMap, {1: 1, 2: 2, 3: 3}); }); test('should return correct frequency map for Queue of strings', () { var queue = Queue(); queue.addAll(['a', 'b', 'b', 'c', 'c', 'c']); - var frequencyMap = queue.frequencies; + var frequencyMap = queue.countFrequency(); expect(frequencyMap, {'a': 1, 'b': 2, 'c': 3}); }); test('should handle empty Queue', () { var queue = Queue(); - var frequencyMap = queue.frequencies; + var frequencyMap = queue.countFrequency(); expect(frequencyMap, {}); }); test('should handle single element Queue', () { var queue = Queue(); queue.add(42); - var frequencyMap = queue.frequencies; + var frequencyMap = queue.countFrequency(); expect(frequencyMap, {42: 1}); }); }); From f4bbe43cbae3fe3336cf7b6c61345252ade7d8e1 Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Sun, 29 Sep 2024 13:56:25 +0300 Subject: [PATCH 08/11] issue-335 converted countFrequency to getter --- test/extensions_test.dart | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/extensions_test.dart b/test/extensions_test.dart index 9b5cd0c..d6af95e 100644 --- a/test/extensions_test.dart +++ b/test/extensions_test.dart @@ -1356,78 +1356,78 @@ void main() { group('FrequencyCounter tests', () { test('should return correct frequency map for List of integers', () { var list = [1, 2, 2, 3, 3, 3]; - var frequencyMap = list.countFrequency(); + var frequencyMap = list.frequencies; expect(frequencyMap, {1: 1, 2: 2, 3: 3}); }); test('should return correct frequency map for List of strings', () { var list = ['a', 'b', 'b', 'c', 'c', 'c']; - var frequencyMap = list.countFrequency(); + var frequencyMap = list.frequencies; expect(frequencyMap, {'a': 1, 'b': 2, 'c': 3}); }); test('should handle empty List', () { var list = []; - var frequencyMap = list.countFrequency(); + var frequencyMap = list.frequencies; expect(frequencyMap, {}); }); test('should handle single element List', () { var list = [42]; - var frequencyMap = list.countFrequency(); + var frequencyMap = list.frequencies; expect(frequencyMap, {42: 1}); }); test('should return correct frequency map for Set of integers', () { // ignore: equal_elements_in_set var set = {1, 2, 2, 3, 3, 3}; - var frequencyMap = set.countFrequency(); + var frequencyMap = set.frequencies; expect(frequencyMap, {1: 1, 2: 1, 3: 1}); }); test('should return correct frequency map for Set of strings', () { // ignore: equal_elements_in_set var set = {'a', 'b', 'b', 'c', 'c', 'c'}; - var frequencyMap = set.countFrequency(); + var frequencyMap = set.frequencies; expect(frequencyMap, {'a': 1, 'b': 1, 'c': 1}); }); test('should handle empty Set', () { var set = {}; - var frequencyMap = set.countFrequency(); + var frequencyMap = set.frequencies; expect(frequencyMap, {}); }); test('should handle single element Set', () { var set = {42}; - var frequencyMap = set.countFrequency(); + var frequencyMap = set.frequencies; expect(frequencyMap, {42: 1}); }); test('should return correct frequency map for Queue of integers', () { var queue = Queue(); queue.addAll([1, 2, 2, 3, 3, 3]); - var frequencyMap = queue.countFrequency(); + var frequencyMap = queue.frequencies; expect(frequencyMap, {1: 1, 2: 2, 3: 3}); }); test('should return correct frequency map for Queue of strings', () { var queue = Queue(); queue.addAll(['a', 'b', 'b', 'c', 'c', 'c']); - var frequencyMap = queue.countFrequency(); + var frequencyMap = queue.frequencies; expect(frequencyMap, {'a': 1, 'b': 2, 'c': 3}); }); test('should handle empty Queue', () { var queue = Queue(); - var frequencyMap = queue.countFrequency(); + var frequencyMap = queue.frequencies; expect(frequencyMap, {}); }); test('should handle single element Queue', () { var queue = Queue(); queue.add(42); - var frequencyMap = queue.countFrequency(); + var frequencyMap = queue.frequencies; expect(frequencyMap, {42: 1}); }); }); From 9c4cf4739cf53d519a227213adfdd632fea82f66 Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Sun, 29 Sep 2024 14:01:03 +0300 Subject: [PATCH 09/11] issue-335 returned the desired string length back --- lib/src/iterable_extensions.dart | 36 +++++++++++++++++++++----------- test/extensions_test.dart | 2 +- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index 91816e9..3e87060 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart @@ -57,7 +57,8 @@ extension IterableExtension on Iterable { } /// The elements that do not satisfy [test]. - Iterable whereNot(bool Function(T element) test) => where((element) => !test(element)); + Iterable whereNot(bool Function(T element) test) => + where((element) => !test(element)); /// Creates a sorted list of the elements of the iterable. /// @@ -81,7 +82,8 @@ extension IterableExtension on Iterable { /// /// The elements are ordered by the [compare] [Comparator] of the /// property [keyOf] of the element. - List sortedByCompare(K Function(T element) keyOf, Comparator compare) { + List sortedByCompare( + K Function(T element) keyOf, Comparator compare) { var elements = [...this]; mergeSortBy(elements, keyOf, compare); return elements; @@ -128,7 +130,8 @@ extension IterableExtension on Iterable { /// Applies [keyOf] to each element in iteration order, /// then checks whether the results are in non-decreasing order /// using the [compare] [Comparator].. - bool isSortedByCompare(K Function(T element) keyOf, Comparator compare) { + bool isSortedByCompare( + K Function(T element) keyOf, Comparator compare) { var iterator = this.iterator; if (!iterator.moveNext()) return true; var previousKey = keyOf(iterator.current); @@ -198,7 +201,8 @@ extension IterableExtension on Iterable { } /// Expands each element and index to a number of elements in a new iterable. - Iterable expandIndexed(Iterable Function(int index, T element) expand) sync* { + Iterable expandIndexed( + Iterable Function(int index, T element) expand) sync* { var index = 0; for (var element in this) { yield* expand(index++, element); @@ -236,7 +240,8 @@ extension IterableExtension on Iterable { /// /// Returns the result of the last call to [combine], /// or [initialValue] if there are no elements. - R foldIndexed(R initialValue, R Function(int index, R previous, T element) combine) { + R foldIndexed( + R initialValue, R Function(int index, R previous, T element) combine) { var result = initialValue; var index = 0; for (var element in this) { @@ -389,7 +394,8 @@ extension IterableExtension on Iterable { /// iterable.groupFoldBy(keyOf, /// (Set? previous, T element) => (previous ?? {})..add(element)); /// ```` - Map groupFoldBy(K Function(T element) keyOf, G Function(G? previous, T element) combine) { + Map groupFoldBy( + K Function(T element) keyOf, G Function(G? previous, T element) combine) { var result = {}; for (var element in this) { var key = keyOf(element); @@ -430,7 +436,8 @@ extension IterableExtension on Iterable { /// var parts = [1, 0, 2, 1, 5, 7, 6, 8, 9].splitBefore(isPrime); /// print(parts); // ([1, 0], [2, 1], [5], [7, 6, 8, 9]) /// ``` - Iterable> splitBefore(bool Function(T element) test) => splitBeforeIndexed((_, element) => test(element)); + Iterable> splitBefore(bool Function(T element) test) => + splitBeforeIndexed((_, element) => test(element)); /// Splits the elements into chunks after some elements. /// @@ -446,7 +453,8 @@ extension IterableExtension on Iterable { /// var parts = [1, 0, 2, 1, 5, 7, 6, 8, 9].splitAfter(isPrime); /// print(parts); // ([1, 0, 2], [1, 5], [7], [6, 8, 9]) /// ``` - Iterable> splitAfter(bool Function(T element) test) => splitAfterIndexed((_, element) => test(element)); + Iterable> splitAfter(bool Function(T element) test) => + splitAfterIndexed((_, element) => test(element)); /// Splits the elements into chunks between some elements. /// @@ -478,7 +486,8 @@ extension IterableExtension on Iterable { /// .splitBeforeIndexed((i, v) => i < v); /// print(parts); // ([1], [0, 2], [1, 5, 7], [6, 8, 9]) /// ``` - Iterable> splitBeforeIndexed(bool Function(int index, T element) test) sync* { + Iterable> splitBeforeIndexed( + bool Function(int index, T element) test) sync* { var iterator = this.iterator; if (!iterator.moveNext()) { return; @@ -512,7 +521,8 @@ extension IterableExtension on Iterable { /// .splitAfterIndexed((i, v) => i < v); /// print(parts); // ([1, 0], [2, 1], [5, 7, 6], [8, 9]) /// ``` - Iterable> splitAfterIndexed(bool Function(int index, T element) test) sync* { + Iterable> splitAfterIndexed( + bool Function(int index, T element) test) sync* { var index = 0; List? chunk; for (var element in this) { @@ -539,7 +549,8 @@ extension IterableExtension on Iterable { /// .splitBetweenIndexed((i, v1, v2) => v1 > v2); /// print(parts); // ([1], [0, 2], [1, 5, 7], [6, 8, 9]) /// ``` - Iterable> splitBetweenIndexed(bool Function(int index, T first, T second) test) sync* { + Iterable> splitBetweenIndexed( + bool Function(int index, T first, T second) test) sync* { var iterator = this.iterator; if (!iterator.moveNext()) return; var previous = iterator.current; @@ -1002,7 +1013,8 @@ extension ComparatorExtension on Comparator { /// /// Compares [R] values by comparing their [keyOf] value /// using this comparator. - Comparator compareBy(T Function(R) keyOf) => (R a, R b) => this(keyOf(a), keyOf(b)); + Comparator compareBy(T Function(R) keyOf) => + (R a, R b) => this(keyOf(a), keyOf(b)); /// Combine comparators sequentially. /// diff --git a/test/extensions_test.dart b/test/extensions_test.dart index d6af95e..83ffb0f 100644 --- a/test/extensions_test.dart +++ b/test/extensions_test.dart @@ -1353,7 +1353,7 @@ void main() { expect(l3.toList(), [4, 5]); }); }); - group('FrequencyCounter tests', () { + group('get frequencies tests', () { test('should return correct frequency map for List of integers', () { var list = [1, 2, 2, 3, 3, 3]; var frequencyMap = list.frequencies; From da963a5a56d4436ba5990f201ee0e979ef89abb0 Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Tue, 1 Oct 2024 10:44:48 +0300 Subject: [PATCH 10/11] issue-335 corrected the description in the comment --- lib/src/iterable_extensions.dart | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index 3e87060..f782085 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart @@ -602,11 +602,16 @@ extension IterableExtension on Iterable { } } - /// Returns a map where the keys are the unique elements of the iterable - /// and the values are the counts of those elements. + /// The count of occurrences of each element. /// - /// for example, ['a', 'b', 'b', 'c', 'c', 'c'].frequencies; - /// returns {'a': 1, 'b': 2, 'c': 3}. + /// The map has an entry for each distinct element of this iterable, + /// as determined by `==`, where the value is the number of eelements + /// in this iterable which are equal to the key. + /// If there are elements that are equal, but not identical, its unspecified + /// which of the elements is used as the key. + /// + /// For example `['a', 'b', 'c', 'b', 'c', 'c'].frequencies` + /// is a map with entries like `{'a': 1, 'b': 2, 'c': 3}`. Map get frequencies { final frequencyMap = {}; for (var item in this) { From 23735665d4adb4f15aaa4180cde83aac3f2d5e4f Mon Sep 17 00:00:00 2001 From: "@kryuchkov_ps" Date: Tue, 1 Oct 2024 13:37:01 +0300 Subject: [PATCH 11/11] issue-335 added 'get frequencies tests extended' group --- lib/src/iterable_extensions.dart | 30 ++++++++++++++----- test/extensions_test.dart | 50 ++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/lib/src/iterable_extensions.dart b/lib/src/iterable_extensions.dart index f782085..3e4a29d 100644 --- a/lib/src/iterable_extensions.dart +++ b/lib/src/iterable_extensions.dart @@ -604,14 +604,28 @@ extension IterableExtension on Iterable { /// The count of occurrences of each element. /// - /// The map has an entry for each distinct element of this iterable, - /// as determined by `==`, where the value is the number of eelements - /// in this iterable which are equal to the key. - /// If there are elements that are equal, but not identical, its unspecified - /// which of the elements is used as the key. - /// - /// For example `['a', 'b', 'c', 'b', 'c', 'c'].frequencies` - /// is a map with entries like `{'a': 1, 'b': 2, 'c': 3}`. + /// The map contains an entry for each unique element of this iterable, + /// as determined by `==`. + /// The value for each key is the number of times that element + /// appears in the iterable. + /// + /// If there are elements that are equal (`==`), + /// but not identical (`identical`), + /// it is unspecified which of the elements is used as the key in the map. + /// For example, if there are multiple lists with the same content, + /// the map will only keep one of them as a key. + /// + /// Example: + /// ```dart + /// ['a', 'b', 'c', 'b', 'c', 'c'].frequencies; + /// Returns: {'a': 1, 'b': 2, 'c': 3}. + /// ``` + /// + /// Note: This method uses `==` to compare elements. + /// For collections # `List`, `Set`, or `Map`, deep equality is not checked. + /// If you need deep equality (e.g., nested lists), + /// consider using a custom equality mechanism. + Map get frequencies { final frequencyMap = {}; for (var item in this) { diff --git a/test/extensions_test.dart b/test/extensions_test.dart index 83ffb0f..3d02625 100644 --- a/test/extensions_test.dart +++ b/test/extensions_test.dart @@ -1431,6 +1431,44 @@ void main() { expect(frequencyMap, {42: 1}); }); }); + + group('get frequencies tests extended', () { + test('list of equal but not identical strings', () { + var list = ['apple', String.fromCharCodes('apple'.codeUnits)]; + var frequencyMap = list.frequencies; + expect(frequencyMap, {'apple': 2}); + }); + + test('list of records', () { + var list = [(1, 'a'), (1, 'a'), (2, 'b'), (1, 'a')]; + var frequencyMap = list.frequencies; + expect(frequencyMap, {(1, 'a'): 3, (2, 'b'): 1}); + }); + + test('list with elements that are objects', () { + var list = [const MyObject(1), const MyObject(1), const MyObject(2)]; + var frequencyMap = list.frequencies; + expect(frequencyMap, {const MyObject(1): 2, const MyObject(2): 1}); + }); + + test('list with equal numbers but different types', () { + var list = [1, 1.0, 1, 1.0]; + var frequencyMap = list.frequencies; + expect(frequencyMap, {1: 4,}); + }); + + test('list with mixed data types', () { + var list = [1, 'one', true, 1, 'one', false]; + var frequencyMap = list.frequencies; + expect(frequencyMap, {1: 2, 'one': 2, true: 1, false: 1}); + }); + + test('list with null values', () { + var list = [null, null, 1, 'null']; + var frequencyMap = list.frequencies; + expect(frequencyMap, {null: 2, 1: 1, 'null': 1}); + }); + }); }); group('Comparator', () { @@ -2125,6 +2163,18 @@ void main() { }); } +class MyObject { + final int id; + const MyObject(this.id); + + @override + bool operator ==(Object other) => + identical(this, other) || other is MyObject && id == other.id; + + @override + int get hashCode => id.hashCode; +} + /// Creates a plain iterable not implementing any other class. Iterable iterable(Iterable values) sync* { yield* values;