У меня есть сценарий, где у меня есть функция, scanForTargets, которая возвращает Observable типа FoundNumber.В FoundNumber мне просто нужно поле ID, которое я могу извлечь из него.Поскольку каждый элемент возвращается в ScanResults Observable, я хочу проверить, соответствует ли поле имени одному из имен в списке целей.Если так, то я хочу это испустить.Например, если я ищу цифры 1 и 2, а scanForTargets () отправляет обратно 1, 2, 3 и 4, то я хочу, чтобы scanForValues отправляла обратно только 1 и 2.
Предупреждениечто я только хочу продолжать делать это до тех пор, пока: 1) не истечет период времени (в этом случае я выбрасываю и выдает ошибку) 2) все элементы в списке строк найдены до истечения времени ожидания.
Что у меня такFar выглядит примерно так, но я не могу заставить его работать на меня, в основном из-за ярлыка остановки один раз / если все цели найдены до истечения времени ожидания.
fun scanForValues(targetList: List<String>): Observable<FoundNumber> {
val scanResult = scanForTargets()
return scanResult.doOnNext {scanResult -> Log.d(TAG, "Found potential target: " + scanResult.name) }
.filter(TargetPredicate(targetList)) //See if it's one of those we want
.timeout(5, TimeUnit.SECONDS) //Wait a max of 5 seconds to find all items
.doOnError { Log.w(TAG, "Failed to scan"}") }
.map{s->scanResult.name}
}
class TargetPredicate(private val targetList: List<String>) : Predicate<ScanResult> { override fun test(scanResult: ScanResult): Boolean {
if(scanResult == null) {
return false
}
return scanResult.name in targetList
}
}
Как я также могу добавить проверку, чтобы остановить, если я найду все элементы в списке?Я не могу просто добавить еще один предикат, верно?
Спасибо.
Обновление: по запросу, вот некоторые данные, чтобы показать, что я имею в виду.
Допустим, что scanForTargets() и вспомогательный код выглядит следующим образом:
var emittedList: List<String?> = listOf(null, "0", "1", "2", "3")
fun scanForTargets(): Observable<FoundNumber> = Observable
.intervalRange(0, emittedList.size.toLong(), 0, 1, TimeUnit.SECONDS)
.map { index -> FoundNumber(emittedList[index.toInt()]) }
data class FoundNumber(val targetId: String?)
Теперь, если scanForValues был вызван со списком 1 и 2, он должен выдать Observable 1, а затем 2.