more stdlib and docs

This commit is contained in:
Sergey Chernov 2025-12-24 18:56:30 +01:00
parent cd2b1a9cb7
commit 5586e027ea
4 changed files with 98 additions and 15 deletions

View File

@ -55,7 +55,7 @@ Here is the sample:
assertEquals( (1..3).joinToString { it * 10 }, "10 20 30")
>>> void
## `sum` and `sumBy`
## `sum` and `sumOf`
These, again, does the thing:
@ -68,17 +68,62 @@ These, again, does the thing:
>>> void
## map and mapNotNull
## map, filter and their variations
Used to transform either the whole iterable stream or also skipping som elements from it:
Used to transform or filter the whole iterable stream:
val source = [1,2,3,4]
// transform every element to string or null:
assertEquals(["n1", "n2", null, "n4"], source.map { if( it == 3 ) null else "n"+it } )
// transform every element to stirng, skipping 3:
// map: transform every element to something else
assertEquals(["n1", "n2", "n3", "n4"], source.map { "n"+it } )
// filter: keep only elements matching the predicate
assertEquals([2, 4], source.filter { it % 2 == 0 } )
// count: count elements matching the predicate
assertEquals(2, source.count { it % 2 == 0 } )
// mapNotNull: transform every element, skipping null results:
assertEquals(["n1", "n2", "n4"], source.mapNotNull { if( it == 3 ) null else "n"+it } )
// filterNotNull: skip all null elements:
assertEquals([1, 2, 4], [1, 2, null, 4].filterNotNull())
>>> void
You can also use flow variations that return a cold `Flow` instead of a `List`, which is useful for large or infinite sequences:
val source = [1, 2, 3, 4]
// filterFlow: returns a Flow of filtered elements
assert( source.filterFlow { it % 2 == 0 } is Flow )
// filterFlowNotNull: returns a Flow of non-null elements
assert( [1, null, 2].filterFlowNotNull() is Flow )
>>> void
## minOf and maxOf
Find the minimum or maximum value of a function applied to each element:
val source = ["abc", "de", "fghi"]
assertEquals(2, source.minOf { it.length })
assertEquals(4, source.maxOf { it.length })
>>> void
## flatten and flatMap
Work with nested collections:
val nested = [[1, 2], [3, 4]]
// flatten: combine nested collections into one list
assertEquals([1, 2, 3, 4], nested.flatten())
// flatMap: map each element to a collection and flatten the result
assertEquals([1, 10, 2, 20], [1, 2].flatMap { [it, it*10] })
>>> void
## findFirst and findFirstOrNull
@ -108,10 +153,21 @@ Search for the first element that satisfies the given predicate:
| isEmpty() | check iterable is empty |
| forEach(f) | call f for each element |
| toMap() | create a map from list of key-value pairs (arrays of 2 items or like) |
| any(p) | true if any element matches predicate `p` |
| all(p) | true if all elements match predicate `p` |
| map(f) | create a list of values returned by `f` called for each element of the iterable |
| indexOf(i) | return index if the first encounter of i or a negative value if not found |
| associateBy(kf) | create a map where keys are returned by kf that will be called for each element |
| findFirst(p) | return first element matching predicate `p` or throw (1) |
| filter(p) | create a list of elements matching predicate `p` |
| count(p) | count elements matching predicate `p` |
| filterFlow(p) | create a [Flow] of elements matching predicate `p` |
| filterNotNull() | create a list of non-null elements |
| filterFlowNotNull() | create a [Flow] of non-null elements |
| minOf(f) | return minimum value of `f` applied to elements |
| maxOf(f) | return maximum value of `f` applied to elements |
| flatten() | flatten nested collections into a single [List] |
| flatMap(f) | map each element with `f` and flatten results into a [List] |
| findFirst(p) | return first element matching predicate `p` or throw (1) |
| findFirstOrNull(p) | return first element matching predicate `p` or `null` |
| first | first element (1) |
| last | last element (1) |
@ -120,13 +176,13 @@ Search for the first element that satisfies the given predicate:
| drop(n) | return new [Iterable] without first n elements |
| dropLast(n) | return new [Iterable] without last n elements |
| sum() | return sum of the collection applying `+` to its elements (3) |
| sumOf(predicate) | sum of the modified collection items (3) |
| sumOf(f) | sum of the modified collection items (3) |
| sorted() | return [List] with collection items sorted naturally |
| sortedWith(comparator) | sort using a comparator that compares elements (1) |
| sortedBy(predicate) | sort by comparing results of the predicate function |
| joinToString(s,t) | convert iterable to string, see (2) |
| reversed() | create a list containing items from this in reverse order |
| shuffled() | create a listof shiffled elements |
| shuffled() | create a list of shuffled elements |
(1)
:: throws `NoSuchElementException` if there is no such element
@ -156,6 +212,8 @@ For high-performance Kotlin-side interop and custom iterable implementation deta
[List]: List.md
[Flow]: parallelism.md#flow
[Range]: Range.md
[Set]: Set.md

View File

@ -158,7 +158,8 @@ List could be sorted in place, just like [Collection] provide sorted copies, in
| `sort()` | in-place sort, natural order | void |
| `sortBy(predicate)` | in-place sort bu `predicate` call result (3) | void |
| `sortWith(comparator)` | in-place sort using `comarator` function (4) | void |
| `shiffle()` | in-place shiffle contents | |
| `shuffle()` | in-place shuffle contents | |
| `toString()` | string representation like `[a,b,c]` | |
(1)
: optimized implementation that override `Array` one

View File

@ -106,4 +106,11 @@ class StdlibTest {
assertEquals([1,2,3,4,5,6], [1,3,5].flatMap { [it,it+1] }.toList() )
""")
}
@Test
fun testCount() = runTest {
eval("""
assertEquals(5, (1..10).toList().count { it % 2 == 1 } )
""")
}
}

View File

@ -15,8 +15,10 @@ fun cached(builder) {
value
}
}
/* Filter elements of this iterable using the provided predicate. */
fun Iterable.filterFlow(predicate) {
/* Filter elements of this iterable using the provided predicate and provide a flow
of results. Coudl be used to map infinte flows, etc.
*/
fun Iterable.filterFlow(predicate): Flow {
val list = this
flow {
for( item in list ) {
@ -27,6 +29,9 @@ fun Iterable.filterFlow(predicate) {
}
}
/*
Filter this iterable and return List of elements
*/
fun Iterable.filter(predicate) {
val result = []
for( item in this ) if( predicate(item) ) result.add(item)
@ -34,14 +39,26 @@ fun Iterable.filter(predicate) {
}
/*
filter out all null elements from this collection (Iterable); collection of
Count all items in this iterable for which predicate return true
*/
fun Iterable.count(predicate): Int {
var hits = 0
this.forEach {
if( predicate(it) ) hits++
}
hits
}
/*
filter out all null elements from this collection (Iterable); flow of
non-null elements is returned
*/
fun Iterable.filterFlowNotNull() {
fun Iterable.filterFlowNotNull(): Flow {
filterFlow { it != null }
}
fun Iterable.filterNotNull() {
/* Filter non-null elements and collect them into a List
*/
fun Iterable.filterNotNull(): List {
filter { it != null }
}