Я использую RxJava / Kotlin Observable#take(), чтобы получить первые 50 элементов из списка. Но оператор #take() ведет себя не так, как должно, в соответствии с документами Rx.
В документации Rx #take() определяется как:
"Emit only the first n items emitted by an Observable"
У меня есть такая функция:
Как мы видим, аргумент pageSize - это 50.
И начальный size из list - это 300.
После этого #take(50) применяется к этому Observable, и на следующей точке останова я все еще получаю список полный размерi.e. size = 300
Но just for the check, если что-то не так с отладчиком или наблюдаемым, я попытался взять только элементы, displayName которых содержит «9», но на этот раз я получаю ожидаемый результат smaller list с 9 в каждом из их #displayName field.
Я считаю, что оператор RxJava/Kotlin's #take() не такой уж сумасшедший, и это только я.




Внимательно посмотрите на тип возвращаемого значения вашего метода - Single<List<FollowersEntity>>. Observable, возвращаемый из remoteFollowersService.getFollowers(), - это нет, Observable, который испускает 300 элементов FollowersEntity - это Observable, который излучает элемент не замужем, и этот единственный элемент - это List, содержащий 300 элементов FollowersEntity. Другими словами, вам нужно вызывать дубль по списку, а не по наблюдаемому.
return remoteFollowersService.getFollowers()
.map { val size = it.size; it } // for debugging
.map { it.take(pageSize) }
.map { val size = it.size; it } // for debugging
.map { it.filter { item -> item.displayName.contains("9") } }
.single(emptyList())
take ведет себя правильно, так как даст вам только 50 «шариков» List<FollowersEntry>. Судя по вашим скриншотам и формулировкам, я предполагаю, что вы хотели 50 FollowersEntry. Между контейнером объектов и самими объектами есть фундаментальное логическое различие. RxJava видит только последовательность объектов типа List<>, но не может знать о вложенных объектах, с которыми вы намеревались работать.
Следовательно, вам нужно либо использовать it.take(50) внутри map (или любую другую функцию коллекций Kotlin), либо развернуть последовательность списков в последовательность записей через flatMapIterable:
getFollowers()
.flatMapIterable(entry -> entry)
.take(50 /* entries this time, not lists */)
Я пытался заснуть, и то же самое пришло мне в голову, я открыл ноутбук и получил ответ, потрясающе ... спасибо :) Разум всегда находит решение для создания после того, как пытается задать хороший вопрос ..
Я не уверен, но я думаю, что вы путаете две разные вещи, здесь оператор
Observable.take()рассматривает выбросы наблюдаемого, а не размер излучаемого списка. Таким образом, если вашremoteFollowersService.getFollowers()будет выдавать более 50 элементов, он вернет только первые 50 из них.