Skip to content

Commit 77f0c6a

Browse files
Average Extension Methods (#49)
* Added the average methods. * Return null if list is empty.
1 parent c53b40a commit 77f0c6a

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ doc/api/
1616

1717
# macOS stuff.
1818
.DS_Store
19+
20+
.vscode/launch.json

lib/iterable_basics.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,22 @@ extension IterableBasics<E> on Iterable<E> {
154154
? 0
155155
: this.fold(0, (prev, element) => prev + addend(element));
156156

157+
/// Returns the average of all the values in this iterable, as defined by
158+
/// [value].
159+
///
160+
/// Returns null if [this] is empty.
161+
///
162+
/// Example:
163+
/// ```dart
164+
/// ['a', 'aa', 'aaa'].average((s) => s.length); // 2
165+
/// [].average(); // null
166+
/// ```
167+
num? average(num Function(E) value) {
168+
if (this.isEmpty) return null;
169+
170+
return this.sum(value) / this.length;
171+
}
172+
157173
/// Returns a random element of [this], or [null] if [this] is empty.
158174
///
159175
/// If [seed] is provided, will be used as the random seed for determining
@@ -237,6 +253,25 @@ extension NumIterableBasics<E extends num> on Iterable<E> {
237253
? this.reduce((a, b) => (a + b) as E)
238254
: this.fold(0, (prev, element) => prev + addend(element));
239255
}
256+
257+
/// Returns the average of all the values in this iterable.
258+
///
259+
/// If [value] is provided, it will be used to compute the value to be
260+
/// averaged.
261+
///
262+
/// Returns null if [this] is empty.
263+
///
264+
/// Example:
265+
/// ```dart
266+
/// [2, 2, 4, 8].average(); // 4.
267+
/// [2, 2, 4, 8].average((i) => i + 1); // 5.
268+
/// [].average() // null.
269+
/// ```
270+
num? average([num Function(E)? value]) {
271+
if (this.isEmpty) return null;
272+
273+
return this.sum(value) / this.length;
274+
}
240275
}
241276

242277
T Function(T, T) _generateCustomMaxFunction<T>(Comparator<T> compare) {

test/iterable_basics_test.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,49 @@ void main() {
407407
});
408408
});
409409

410+
group('average', () {
411+
test('returns average on list of numbers', () {
412+
final nums = <int>[2, 2, 4, 8];
413+
final ints = <int>[2, 2, 2];
414+
final numbers = [1.5, 1.5, 3, 3];
415+
416+
expect(nums.average(), 4);
417+
expect(ints.average(), 2);
418+
expect(ints.average((n) => n * 2), 4);
419+
expect(nums.average((n) => n + 1), 5);
420+
expect(numbers.average(), 2.25);
421+
});
422+
423+
test('returns null on empty lists', () {
424+
expect(<int>[].average(), null);
425+
expect(<double>[].average(), null);
426+
expect(<num>[].average((n) => n * 2), null);
427+
expect(<String>[].average((s) => s.length), null);
428+
expect(<int>[].average((n) => n * 2), null);
429+
});
430+
431+
test('returns average of custom value function', () {
432+
final strings = ['a', 'aa', 'aaa'];
433+
434+
expect(strings.average((s) => s.length), 2);
435+
});
436+
437+
test('works on sets', () {
438+
final strings = {'a', 'aa', 'aaa'};
439+
440+
expect(strings.average((s) => s.length), 2);
441+
});
442+
443+
test('works on dynamic list with custom value function', () {
444+
final items = [1, 'aaa', 2.0];
445+
446+
expect(items.average((a) => _getItemSize(a)), equals(2));
447+
448+
items.add(0.5);
449+
expect(items.average((a) => _getItemSize(a)), equals(1.625));
450+
});
451+
});
452+
410453
group('sum', () {
411454
test('returns sum on list of numbers', () {
412455
final nums = [1.5, 2, 3];

0 commit comments

Comments
 (0)