These intermediate operators are also called transform operators
These operators are executed for every emission of the flow
It returns a new and transformed flow
Map
Observation
Using the map-operator we can convert the form of one type of input into another type
In the example below, We have converted from integer to String
It seems like you want to create a table in a GitHub README file to describe three operators for Kotlin's Flow API: map, mapNotNull, and mapLatest. Below is an example table format that you can use in your README file:
Operator
Description
map
Transforms each emitted item by applying a given function, producing a new flow of transformed items.
mapNotNull
Transforms each emitted item by applying a given function, excluding null results from the new flow.
mapLatest
Similar to map, but only emits the result of the latest transformation when a new item is emitted.
You can copy and paste this table into your README file and fill in the descriptions for each operator. Additionally, you can provide examples or usage patterns for better understanding. Here's a more detailed explanation of each operator:
map: The map operator transforms each item emitted by the flow by applying a given function. It creates a new flow that emits the transformed items. This is useful when you want to perform a one-to-one transformation on each item in the flow.
mapNotNull: Similar to map, the mapNotNull operator transforms each item emitted by the flow using a given function. However, it excludes null results from the new flow. This is useful when you want to filter out null values resulting from the transformation.
mapLatest: The mapLatest operator is similar to map, but it only emits the result of the latest transformation when a new item is emitted in the original flow. If a new item is emitted before the previous transformation completes, the result of the previous transformation is ignored. This is useful when you want to ensure that only the latest result is considered, discarding outdated transformations.
Code
privateval flowOfIntegers = flowOf(1, 2, 3, 4, 5)
viewModelScope.launch {
flowOfIntegers.map {
it.toString()
}.collect {
if(it isString){
// Use smart cast to check if it is stringprintln("Received value: -->$it")
}
}
}
Output
Received value:-->1Received value:-->2Received value:-->3Received value:-->4Received value:-->5
Filter
Observation
Here we pass a collection of items but emit only those that pass a predicate test
Operator
Description
flowOfIntegers.filter { }
Filters items emitted by the flow based on a given predicate. Only items that satisfy the predicate are included in the new flow.
flowOfIntegers.filterNot { }
Filters items emitted by the flow based on a given predicate. Only items that do not satisfy the predicate are included in the new flow.
flowOfIntegers.filterIsInstance<Int>{ }
Filters items emitted by the flow and includes only those that are instances of the specified type (Int in this case).
Code
val flowOfIntegers = flowOf(1, 2, 3, 4, 5)
viewModelScope.launch {
flowOfIntegers.filter {
// We use modulus function to check if the number is divisible by 2
it%2==0
}.collect{
println("Received value: -->$it")
}
}
Output
Received value:-->2Received value:-->4
Take
Observation
It is called a sizing operator
Operator
Description
flowOfIntegers.take { }
Limits the number of items emitted by the flow to a specified count.
flowOfIntegers.takeIf { }
Conditional operator; takes items from the flow if a specified condition is true, otherwise returns an empty flow.
flowOfIntegers.takeWhile { }
Takes items from the flow as long as a specified predicate is true; stops when the predicate becomes false.
flowOfIntegers.takeUnless { }
Opposite of takeIf; takes items from the flow if a specified condition is false, otherwise returns an empty flow.
Received value:-->2Received value:-->3Received value:-->4Received value:-->5
Transform
Observation
We can transform the data apply some predicate conditions and emit the new value,
We can also emit multiple emissions
This is basically applying a collection of operators together and emitting the emission downstream
Output
Received value:-->2Received value:-->4
Code
funtransformOperator() {
val scope =CoroutineScope(EmptyCoroutineContext)
scope.launch {
flowOfIntegers.transform {
if((it%2)==0){
// Elements that are divisible by 2
emit(it)
}
}.collect{
println("Received value: -->$it")
}
}
}
Debounce
Observation
Using this operator we can discard the emissions in a certain period frame.
Some emissions will be lost from this time frame
This is helpful to drop some duplicate emissions from the period frame.
One example is when the mouse is moving and a lot of emissions might be sent from the position coordinates of the mouse, and we might be interested in certain coordinates in it.