littlelightcz
10/11/2018, 7:10 PMList<Result<T>> (when using runCatching {}) which would help be execute some action in case there have been some failures etc.? Since I think this is (or will be) a very common design pattern - similarly as there is a convenience ext. function for List<Deferred<T>>.awaitAll().
Recently I was thinking it could be done in the similar fashion as the current .onFailure() and .onSuccess() except that the lambda would take List<Throwable> or List<T> as an argument (respectively).
Currently what I need to do on such list, is: (1) filter { it.isFailure}, then (2) I need to check that it is not empty, and not until now (3) I can do something with it. With the above proposal the first 2 steps would be unnecessary and I would be able to define just the part which would execute only if there was at least 1 failed Result. Similarly it could work for successful Result values.gildor
10/12/2018, 1:05 AMmapNonNull { it.getOrNull() }gildor
10/12/2018, 1:07 AMmap { it.getOrThrow() }gildor
10/12/2018, 1:09 AMlittlelightcz
10/12/2018, 4:40 PMval results = (1..5).map {
runCatching {
if (it % 2 == 0) throw Exception("Oops!") else it
}
}
val failed = results.filter { it.isFailure }
if (failed.isNotEmpty()) {
println("There were ${failed.size} failures and the first one was: ${failed.first().exceptionOrNull()}")
}
println("Succeeded were:")
results.filter { it.isSuccess }.forEach { println(it.getOrNull()) }
Wouldn't it be much better if I could write it e.g. like this?
(1..5).map {
runCatching {
if (it % 2 == 0) throw Exception("Oops!") else it
}
}
.onFailed { println("There were ${it.size} failures and the first one was: ${it.first()}") }
.onSucceeded { succeeded ->
println("Succeeded were:")
succeeded.forEach { println(it) }
}gildor
10/13/2018, 3:29 AMgildor
10/13/2018, 3:29 AMgroupBygildor
10/13/2018, 3:31 AMgildor
10/13/2018, 3:32 AMgildor
10/13/2018, 3:35 AMval succeed = (1..5).mapNonNull {
if (it % 2 == 0) {
println("Failure of operation $it")
null
} else {
it
}
}
}
println("Succeeded were:")
succeed.forEach { println(it) }gildor
10/13/2018, 3:35 AMgildor
10/13/2018, 3:36 AMlittlelightcz
10/23/2018, 5:41 PM.onFailed { } as I was thinking about it cannot be used. So I am still with your mapNotNull solution (it saves one filter call 😁), so thanks so far 🙂dave08
11/01/2018, 7:20 AMval (successful, failed) = results.partition { it.isSuccess }, instead of two filters...littlelightcz
11/01/2018, 7:00 PMPair<List<Result<T>>, List<Result<T>>>. If it gave me Pair<List<T>, List<Throwable>> then I would be good with it 😁.dave08
11/02/2018, 8:46 AMlittlelightcz
11/02/2018, 6:11 PMinline fun <T: Any> Collection<Result<T>>.partitionByResult() = mapNotNull { it.getOrNull() } to mapNotNull { it.exceptionOrNull() }
Then having this example:
fun main() {
val results = listOf(
runCatching { "Hi" },
runCatching { throw Exception("Oops") }
)
val (ok, errors) = results.partitionByResult()
println(ok)
println(errors)
}
The output is:
[Hi]
[java.lang.Exception: Oops]ilya.gorbunov
11/02/2018, 9:22 PMpartitionBySuccess. Could you open an issue for this proposal?littlelightcz
11/03/2018, 6:36 PM