Filter list of objects in RxJava
Asked Answered
A

4

16

I am trying to filter the list on the basis of it's property. For example, Sensors class has a property isActive and I want to get all the objects with isActive as true but I am unable to do it. I tried different ways but I didn't find the solution. Can someone help me to do it?

Here is my code:

mCompositeDisposable.add(
    fcService.getStationList()
    .subscribeOn(Schedulers.io())
    .flatMap(stations -> {
        return fcService.getSensorList(stations.get(0).getName().getOriginal());}
    ).subscribe(this::handleSensors, this::handleError));
Alejoa answered 8/2, 2018 at 12:12 Comment(0)
S
33

First, you need to emit each item from the List individually. That can be achieved using flatMap() and Observable.fromIterable(Iterable).

Then apply filter() operator. Lastly, collect all of those items into list again using toList().


    service.getSensorsList()
              .flatMap(Observable::fromIterable)
              .filter(sensor -> sensor.isActive())
              .toList()
              .subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread())
              .subscribe(this::handleSensors, this::handleError)

Sirois answered 8/2, 2018 at 12:22 Comment(2)
Thanks @azizbekian. This solution worked but not exactly the way I want. It is returning one sensor at a time in handleSensors and not a List<Sensor>. This mean, let's say there are 100 sensors returned and only 15 sensors have isActive == true then handleSensors is getting called 15 times. Can I just return the List<Sensor> so that handleSensors is called only once?Alejoa
Thanks it worked. I missed .toList() in my previous try.Alejoa
F
22

Kotlin users can use a more simple approach like below.

fcService.getStationList()
    .map(it.filter {sensor -> sensor.isActive()})

It is possible because Kotlin has so many list operators itself, so for the filtering part you don't have to use rx. it.filter {sensor -> sensor.isActive()} is pure Kotlin code.

Ferrari answered 10/11, 2018 at 10:28 Comment(2)
The questions asks for a solution using RxJava, not Kotlin.Sirois
@Sirois I know! I'm just offering an alternative solution to those who use Kotlin.Ferrari
E
1

I wanted to delete the values of a list based on Rejex and finally return a Observable list model

fun getList(): Observable<List<Destination>> {
    return appDataBase.dao().getAllList().flatMap {
        Observable.fromIterable(it).filter { destination ->
            destination.number.matches(regex = "[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\\s\\./0-9]*\$".toRegex())
        }.toList().toObservable()
    }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())

}

I hope this helps

Estrella answered 27/9, 2020 at 6:17 Comment(0)
S
0

This code is working for me.

import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.observers.DisposableSingleObserver
import io.reactivex.schedulers.Schedulers
import java.util.*
import javax.inject.Inject
import kotlin.collections.ArrayList

    class MainPresenter {
    ....

    var disposable: Disposable? = null
    fun filterArticlesList(text: String?) {
            if (text == null || text.isEmpty()) {
                LogDebug.d("filterArticlesList", "cleared text")
                staticArticlesListFiltered = staticArticlesList
                getView()?.onFilterListSuccess(staticArticlesListFiltered)
            } else {
                val locale = Locale.getDefault()
                val textLower = text.toLowerCase(locale)
                disposable?.dispose()
                disposable = (Observable.fromIterable(staticArticlesList)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .filter { article -> article.title.toLowerCase(locale).contains(textLower) }
                    .toList()
                    .subscribeWith(FilterObserver(this@MainPresenter)))
            }
        }

    }
    class FilterObserver(private val presenter: MainPresenter) :
        DisposableSingleObserver<List<Article>>() {
        override fun onSuccess(t: List<Article>) {
            LogDebug.d("FilterObserver", "onSuccess")
        }

        override fun onError(e: Throwable) {
            LogDebug.e("FilterObserver", "onError", e)
        }

    }
Scientist answered 6/9, 2019 at 12:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.