我有一个可以观察到的解析大型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个元素。
因此,我想连续接收一个可观察到的相同键,而当我拥有不同的键时,我想接收另一个可观察到的(分组依据)。
提前谢谢
答案 0 :(得分:1)
一种可能的解决方案是编写自定义ObservableTransformer
。
我认为,最简单的解决方案是根据下一条规则将项目分组:if 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])]。
该解决方案并不干净,但是可以根据需要运行。