Open chachako opened 3 years ago
Why would you need it with Flow? What kind of code do you write that needs it?
Why would you need it with Flow? What kind of code do you write that needs it?
In the data return of Android-DataStore
, sometimes I need to ensure that the data contains the data I want, then should I use any { true }
? In addition, I used a Flow
to construct a folder, I also need to use any
to determine whether there is a matches file in it
Having determined if it contains the data you need, what are you doing next? Do you run the source flow again to actually extract the data or what? Can you give an example snipped of code in which you envision that any
is going to be useful?
(This is a side note, not a resolution of any kind) It looks like these operations are simple enough to introduce them in place:
public suspend fun <T> Flow<T>.any(predicate: suspend (T) -> Boolean): Boolean =
dropWhile { !predicate(it) }.firstOrNull() != null
public suspend fun <T> Flow<T>.all(predicate: suspend (T) -> Boolean): Boolean =
dropWhile { predicate(it) }.firstOrNull() == null
public suspend fun <T> Flow<T>.none(predicate: suspend (T) -> Boolean): Boolean =
all { !predicate(it) }
Such implementations can be easily modified to instead output the example (or the counter-example) of the matching element, one just has to remove the comparisons with null
.
(This is a side note, not a resolution of any kind) It looks like these operations are simple enough to introduce them in place:
Not so simple...
println(flowOf(null).any { it == null }) // false
println(flowOf(null).all { it != null }) // true
println(flowOf(null).none { it == null }) // true
I'd be grateful for adding Flow<Boolean>.all()
and Flow<Boolean>.any()
to the library (none()
is just !any()
).
I use the following shortcuts in my project, but it'd be nice if they came included:
suspend fun Flow<Boolean>.all() = firstOrNull { !it } == null
suspend fun Flow<Boolean>.any() = firstOrNull { it } != null
They're useful for getting the conjunction/disjunction of deferreds, with short-circuiting, e.g.:
listOf(a, b).map { it::await.asFlow() }.merge().all()
vs.
a.await() && b.await() // Infinitely slower, if b completes false while a never completes
This can make the collect result more concise, just like
list.any {it.is..}