extension First on Iterable { T? firstWhereOrNull( bool Function(T element) test, ) { try { return firstWhere(test); } on StateError { return null; } } T? get firstOrNull { try { return first; } on StateError { return null; } } /// splits a list into a map of {id:list} pairs /// /// the id is supplied by the [deriveKey] method Map> divideByKey( V Function(T e) deriveKey, ) { final result = >{}; for (final e in this) { final key = deriveKey(e); if (result[key] == null) result[key] = []; result[key]!.add(e); } return result; } T get secondLastItem => toList().reversed.elementAt(1); } extension IntersperseDivider on List { void intersperseDivider(T divider) { final prevState = toList(); clear(); for (int i = 0; i < prevState.length; i++) { // Add the current widget to the new list add(prevState.elementAt(i)); if (i == prevState.length - 1) break; add(divider); } } } extension Math on Iterable { T? deriveMaximum() => fold( firstOrNull, (prev, e) => prev == null ? null : e > prev ? e : prev, ); T? deriveMinimum() => fold( firstOrNull, (prev, e) => prev == null ? null : e < prev ? e : prev, ); num calculateAverage() => fold( 0, (prev, e) => prev += e, ) / length; num calculateSum() => fold( 0, (prev, e) => prev += e, ); }