Kotlin flow: собирать только элементы, которые повторяются как минимум N раз
Я использую функцию распознавания символов ML Kit, и иногда первые несколько значений неверны, и только через некоторое время камера стабилизируется и выдает правильные значения. Я не хочу отбрасывать первые значения X, потому что я не знаю, сколько элементов будет содержать поток. Поэтому лучше всего было бы использовать какое-то условие, которое сравнивает текущий элемент с предыдущим, но не уверен.
Есть ли в Kotlin Flow API функция, которая будет сравнивать собранные значения и собирать только то, что произошло не менее N раз?
private val _detectedValues = ConflatedBroadcastChannel<String>()
val detectedFlow = _detectedValues
.asFlow()
.map { it.replace(" ", "") }
.filter { it.checkRegex() }
.onEach {
Log.i(TAG, "detected: $it")
}
1 ответ
Насколько я знаю, встроенного способа сделать это нет, но вы можете сделать это:
fun <T> Flow<T>.repeated(times: Int): Flow<T> {
val map = mutableMapOf<T, Int>()
return transform { value ->
val count = (map[value] ?: 0) + 1
map[value] = count
if (count >= times) {
return@transform emit(value)
}
}
}
При этом используется карта, чтобы отслеживать, сколько раз было отправлено каждое значение. Затем, если значение генерируется достаточное количество раз, оно испускается посредством преобразования.
channel.asFlow()
.repeated(3)
.collect {
// Do something.
}