diff --git a/README.md b/README.md index 1722ed9..7280c14 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,22 @@ final increasingSubSequences = list.chunkWhile((a, b) => a + 1 == b); `splitWhen` is the opposite of `chunkWhile` that starts a new chunk every time the predicate _didn't_ match. +### .modifyWhere() + +Applies a given modifier as long as predicate is true: +```dart +final values = [1, 2, 3]; +values.modifyWhere((v) => v > 1, (v) => -v); // [1, -2, -3] +``` + +### .modifyFirstWhere() + +Applies the modifier to the first element that matches predicate: +```dart +final values = [1, 2, 3]; +values.modifyWhere((v) => v > 1, (v) => -v); // [1, -2, 3] +``` + ## String ### .capitalize diff --git a/lib/src/iterable.dart b/lib/src/iterable.dart index 1b17168..963de81 100644 --- a/lib/src/iterable.dart +++ b/lib/src/iterable.dart @@ -1381,3 +1381,40 @@ extension IterableStartsWithExtension on Iterable { return true; } } + +extension IterableModifyWhereExtension on Iterable { + /// Applies [modifier] to all elements matching the given [predicate] + /// + /// ```dart + /// final values = [1, 2, 3]; + /// values.modifyWhere((v) => v > 1, (v) => -v); // [1, -2, -3] + /// ``` + Iterable modifyWhere( + bool Function(T) predicate, + T Function(T) modifier, + ) { + return map((item) => predicate(item) ? modifier(item) : item); + } +} + +extension IterableModifyFirstWhereExtension on Iterable { + /// Applies [modifier] to the first element matching the given [predicate] + /// + /// ```dart + /// final values = [1, 2, 3]; + /// values.modifyWhere((v) => v > 1, (v) => -v); // [1, -2, 3] + /// ``` + Iterable modifyFirstWhere( + bool Function(T) predicate, + T Function(T) modifier, + ) { + bool modified = false; + return modifyWhere( + (v) => !modified && predicate(v), + (v) { + modified = true; + return modifier(v); + }, + ); + } +} diff --git a/test/iterable_test.dart b/test/iterable_test.dart index 1017278..43c2ac1 100644 --- a/test/iterable_test.dart +++ b/test/iterable_test.dart @@ -1003,5 +1003,47 @@ void main() { expect([null, 1, 2, 3].startsWith([null, 1]), true); expect([1, null, 3].startsWith([1, null]), true); }); + + test('.modifyWhere()', () { + final items = [1, 2, 3, 4, 5, 6]; + + expect( + items.modifyWhere((v) => v < 3, (i) => -i), + [-1, -2, 3, 4, 5, 6], + ); + expect( + items.modifyWhere((v) => v > 3, (i) => -i), + [1, 2, 3, -4, -5, -6], + ); + expect( + items.modifyWhere((v) => v < 0, (i) => -i), + [1, 2, 3, 4, 5, 6], + ); + expect( + items.modifyWhere((v) => v > 0, (i) => i * 2), + [2, 4, 6, 8, 10, 12], + ); + }); + + test('.modifyFirstWhere()', () { + final items = [1, 2, 3, 4, 5, 6]; + + expect( + items.modifyFirstWhere((v) => v < 3, (i) => -i), + [-1, 2, 3, 4, 5, 6], + ); + expect( + items.modifyFirstWhere((v) => v > 3, (i) => -i), + [1, 2, 3, -4, 5, 6], + ); + expect( + items.modifyFirstWhere((v) => v < 0, (i) => -i), + [1, 2, 3, 4, 5, 6], + ); + expect( + items.modifyFirstWhere((v) => v > 0, (i) => i * 2), + [2, 2, 3, 4, 5, 6], + ); + }); }); }