Skip to content

Commit

Permalink
feat: new methods firstNotNullOf and firstNotNullOfOrNull for KtList
Browse files Browse the repository at this point in the history
Signed-off-by: Hugo Branco <[email protected]>
  • Loading branch information
hugobrancowb committed Oct 2, 2022
1 parent 64323fc commit 8535411
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -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
.idea
.vscode
22 changes: 22 additions & 0 deletions lib/src/collection/kt_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,28 @@ extension KtListExtensions<T> on KtList<T> {
}
}

/// 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>(R? Function(T?) transform) {
final KtList<R> 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>(R? Function(T?) transform) {
final KtList<R> 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>(R initial, R Function(T, R acc) operation) {
if (isEmpty()) return initial;
Expand Down
50 changes: 50 additions & 0 deletions test/collection/list_extensions_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<NoSuchElementException>()),
);
});

test("should throw if the list is empty", () {
final list = listOf();
expect(
() => list.firstNotNullOf((i) => i == "a" ? i : null),
throwsA(const TypeMatcher<NoSuchElementException>()),
);
});
});

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");
Expand Down

0 comments on commit 8535411

Please sign in to comment.