Использование RXJava groupby с последовательными элементами - PullRequest
0 голосов
/ 26 сентября 2018

Я наблюдаю, что анализирую большой CSV-файл (не помещается в памяти) и испускает такие элементы, как:

[{id=1, childId=1}, {id=1, childId=2}, {id=1, childId=3}, {id=2, childId=5}, {id=2, childId=6}, {id=1, childId=23}, {id=1, childId=18}]

один элемент за строкой.

При использовании groupBy мойвывод выглядит примерно так:

[{id=1, childs=1,2,**323, 18**}, {id=2, childs=5,6}]

Это нормально для groupBy.Но мне нужно получить сгруппированные элементы для последовательных элементов, поэтому я хочу получить последние элементы с id = 1 в другом элементе.Всего я хотел бы получить 3 элемента.

Поэтому я хочу получить одну наблюдаемую для одного и того же ключа последовательно, а когда у меня есть другой ключ, я хочу получить другую наблюдаемую (сгруппировать по).

Заранее спасибо

1 Ответ

0 голосов
/ 26 сентября 2018

Одним из возможных решений является написание пользовательского ObservableTransformer.На мой взгляд, самое простое решение - разделить элементы по группам в соответствии со следующим правилом: если cell.Id! = PreviousCell.Id поместить его в другую группу.

data class Cell(val id: Int, val childId: Int)

Observable.fromIterable(cells)
                .map(object: Function<Cell, Pair<Int, Cell>> {
                    var latest: Int? = null
                    var groupNumber: Int = 0

                    override fun apply(t: Cell): Pair<Int, Cell> {
                        if(t.id != latest) {
                            latest = t.id
                            groupNumber++
                        }
                        return Pair(groupNumber, t)
                    }

                })
                .groupBy { it.first }

После этого все последовательные ячейки с одинаковымиid будет в одной группе.Теперь вы можете делать все, что хотите.Для получения ожидаемого результата используйте следующий подход:

Observable.fromIterable(cells)
            .map(object: Function<Cell, Pair<Int, Cell>> {
                var latest: Int? = null
                var groupNumber: Int = 0

                override fun apply(t: Cell): Pair<Int, Cell> {
                    if(t.id != latest) {
                        latest = t.id
                        groupNumber++
                    }
                    return Pair(groupNumber, t)
                }

            })
            .groupBy { it.first }
            .flatMapSingle { group ->
                return@flatMapSingle group.reduce(Pair(group.key!!, mutableListOf())) { acc: Pair<Int, MutableList<Int>>, el: Pair<Int, Cell> ->
                    acc.second.add(el.second.childId)
                    return@reduce acc
                }
            }.toList()
            .subscribe({
                Log.d("TAG", it.toString())
            }, { e -> e.printStackTrace() })

Выход будет [(1, [1, 2, 3]), (2, [5, 6]), (3, [23, 18])].

Это решение не чистое, но оно работает так, как вам нужно.

...