Skip to content

Commit

Permalink
Merge pull request #73 from matthias-prevost/sumBy-handle-empty-list
Browse files Browse the repository at this point in the history
Enable empty lists inferred as double (eg: <double>[]) to return a zero of type double
  • Loading branch information
marcglasberg committed Mar 22, 2024
2 parents da5b92e + 49c4a51 commit d8f417d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
19 changes: 19 additions & 0 deletions lib/src/base/iterable_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,32 @@ extension FicIterableExtension<T> on Iterable<T> {
/// expect(['a', 'ab', 'abc', 'abcd', 'abcde'].sumBy((e) => e.length), 15);
/// ```
N sumBy<N extends num>(N Function(T element) mapper) {
// If the iterable is empty but N is double
// then result will be an int because 0 is an int
// therefore result as N (which in this case will be: 0 as double)
// will throw an error
if (isEmpty) {
return _zeroOf<N>();
}

num result = 0;
for (final value in this) {
result = result + mapper(value);
}
return result as N;
}

/// Returns a zero of type [N].
N _zeroOf<N extends num>() {
// num is a sealed class with only two subclasses: int and double
// therefore this function should never throw
return switch (N) {
const (int) => 0 as N,
const (double) => 0.0 as N,
_ => throw UnsupportedError("Unsupported type: $N"),
};
}

/// The arithmetic mean of the elements of a non-empty iterable.
/// The arithmetic mean is the sum of the elements divided by the number of elements.
/// If iterable is empty it returns 0.
Expand Down
2 changes: 2 additions & 0 deletions test/base/iterable_extension_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ void main() {
expect(['a'].sumBy((e) => e.length), 1);
expect(['a', 'ab', 'abc', 'abcd', 'abcde'].sumBy((e) => e.length), 15);
expect(['a', 'ab', 'abc', 'abcd', 'abcde'].map((e) => e.length).sum, 15);
expect(<double>[].sumBy((e) => e), 0.0);
expect(<int>[].sumBy((e) => e), 0);
});

test('averageBy', () {
Expand Down

0 comments on commit d8f417d

Please sign in to comment.