Search code examples
androidkotlinrx-java2

Filtering list inside Observable collection


I want to filter List <Notification> which is inside Observable collection by the specified event.

Here is a Retrofit call:

@GET("/notifications")
Observable<NotificationCollection> getNotifications(@Query("page") Integer page);

NotificationCollection model:

class NotificationCollection {
         var items: List<Notification>? = null
         var pagination: Pagination? = null
}

Notification model:

class Notification {
        var event: String? = null
        var id: Long? = null
        var data: NotificationData? = null
}

In my helper class, I return Observable to interactor:

override fun getNotifications(page: Int): Observable<NotificationCollection> {
        return service.getNotifications(page)
    }

I tried a couple of approaches:

override fun getNotifications(page: Int): Observable<NotificationCollection> {
return service.getNotificationsTimeline(page)
    .filter { it.items?.get(0)?.event == "STORY"}
}

Here I want to apply a predicate to all list items and not only to the ones I define by an index. Is there a way to make something like .filter { it.items.event = "STORY"} ?

Another approach I tried using flatMap here which makes more sense to me but I don't see the way how to map my filtered result to the original response type of Observable<NotificationCollection> and not to the Observable<Notification> like here :

return service.getNotifications(page)
    .flatMap { Observable.fromIterable(it.items) }
    .filter {it.event == "STORY"}

The easiest way would be to apply filter function in my presenter class with flatMap but I want to generalize my solution because the method in the helper class is called in different places. So I want to make the list filtered here.

So, is there a way to filter the list inside Observable collection and return the original response type of Observable<NotificationCollection>?


Solution

  • You should use 'filter' and 'any' together.

    class Test {
        init {
           val testList = listOf(
                   TestData("1","1", listOf("1a")),
                   TestData("2","2", listOf("2b")),
                   TestData("3","3", listOf("3c")))
    
            val result = testList.filter { item ->
                item.c.any { it == "STORY" }
            }
        }
    }
    
    data class TestData(val a: String, val b: String, val c: List<String>)