From 85354115c6296de794534bd7fc5b2ff8288c4c81 Mon Sep 17 00:00:00 2001 From: Hugo Branco Date: Sun, 2 Oct 2022 11:59:39 -0300 Subject: [PATCH] feat: new methods firstNotNullOf and firstNotNullOfOrNull for KtList Signed-off-by: Hugo Branco --- .gitignore | 5 ++- lib/src/collection/kt_list.dart | 22 ++++++++++ test/collection/list_extensions_test.dart | 50 +++++++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ccf2f67e..ebcc397a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,17 @@ # Files and directories created by pub .dart_tool/ .packages + # Remove the following pattern if you wish to check in your lock file pubspec.lock # Conventional directory for build outputs build/ out/ +coverage/ # Directory created by dartdoc doc/api/ -.idea \ No newline at end of file +.idea +.vscode \ No newline at end of file diff --git a/lib/src/collection/kt_list.dart b/lib/src/collection/kt_list.dart index be0050f0..eb825cef 100644 --- a/lib/src/collection/kt_list.dart +++ b/lib/src/collection/kt_list.dart @@ -183,6 +183,28 @@ extension KtListExtensions on KtList { } } + /// Returns the first non-null value after applying the given [transform] + /// function, throwing a [NoSuchElementException] exception if there is no + /// such value. + R firstNotNullOf(R? Function(T?) transform) { + final KtList mappedList = mapNotNull(transform); + + if (mappedList.isEmpty()) { + throw const NoSuchElementException( + "Collection contains no element different than null after transform.", + ); + } + + return mappedList.first(); + } + + /// Returns the first non-null value after applying the given [transform] + /// function; `null` will be returned if there is no such value. + R? firstNotNullOfOrNull(R? Function(T?) transform) { + final KtList mappedList = mapNotNull(transform); + return mappedList.firstOrNull(); + } + /// Accumulates value starting with [initial] value and applying [operation] from right to left to each element and current accumulator value. R foldRight(R initial, R Function(T, R acc) operation) { if (isEmpty()) return initial; diff --git a/test/collection/list_extensions_test.dart b/test/collection/list_extensions_test.dart index 4e1d55f6..b5eae202 100644 --- a/test/collection/list_extensions_test.dart +++ b/test/collection/list_extensions_test.dart @@ -185,6 +185,56 @@ void testList( }); }); + group("firstNotNullOf", () { + test("should return the first element, which is not null", () { + final list = listOf("a", "a", "c"); + expect(list.firstNotNullOf((i) => i == "a" ? i : null), "a"); + }); + + test("should return the third element, which is the first not null", () { + final list = listOf("a", "a", "c"); + expect(list.firstNotNullOf((i) => i == "c" ? i : null), "c"); + }); + + test("should throw if the list contains only null elements", () { + final list = listOf("a", "a", "a"); + expect( + () => list.firstNotNullOf((i) => i == "c" ? i : null), + throwsA(const TypeMatcher()), + ); + }); + + test("should throw if the list is empty", () { + final list = listOf(); + expect( + () => list.firstNotNullOf((i) => i == "a" ? i : null), + throwsA(const TypeMatcher()), + ); + }); + }); + + group("firstNotNullOfOrNull", () { + test("should return the first element, which is not null", () { + final list = listOf("a", "a", "c"); + expect(list.firstNotNullOfOrNull((i) => i == "a" ? i : null), "a"); + }); + + test("should return the third element, which is the first not null", () { + final list = listOf("a", "a", "c"); + expect(list.firstNotNullOfOrNull((i) => i == "c" ? i : null), "c"); + }); + + test("should return null if the list contains only null elements", () { + final list = listOf("a", "a", "a"); + expect(list.firstNotNullOfOrNull((i) => i == "c" ? i : null), null); + }); + + test("should return null if the list is empty", () { + final list = listOf(); + expect(list.firstNotNullOfOrNull((i) => i == "a" ? i : null), null); + }); + }); + group("getOrElse", () { test("get item", () { final list = listOf("a", "b", "c");