Rx java 将操作应用于所有以前发出的项

Rx java 将操作应用于所有以前发出的项,rx-java,reactive-programming,rx-kotlin,Rx Java,Reactive Programming,Rx Kotlin,我有一个项目队列,一旦服务器可访问,将发送这些项目: val队列历史记录:可观察 QueuedItem是: 数据类QueuedItem(val-item:item,val-sent:Boolean=false) queueHistory永远不会完成,它只记录一个项目排队等待发送时的时间onNext(QueuedItem(item1,false),然后记录它被发送时的时间onNext(QueuedItem(item1,true) 我想做的是获取当前有多少未发送项目的计数。 我的问题的主要原因是列表

我有一个项目队列,一旦服务器可访问,将发送这些项目:
val队列历史记录:可观察

QueuedItem是:
数据类QueuedItem(val-item:item,val-sent:Boolean=false)

queueHistory永远不会完成,它只记录一个项目排队等待发送时的时间
onNext(QueuedItem(item1,false)
,然后记录它被发送时的时间
onNext(QueuedItem(item1,true)

我想做的是获取当前有多少未发送项目的计数。

我的问题的主要原因是列表没有完成,我最初考虑使用
collect
,但这需要一个完整的列表

我在玩
scan
之类的东西
queueHistory.scan{items:ScannedItems,item->ScannedItems(arrayOf(*items,item),0)}

我可以保存到目前为止遇到的项目的当前列表,但scan希望所有项目都是相同的类型

我的另一个想法是

queueHistory
            .groupBy { it.item }
            .flatMapSingle { it.toList() }
            .map { it.size % 2 }
但是toList()需要一个有限的列表

任何想法都将受到欢迎。

有一个
#scan
重载,它接受一个种子值和一个lambda,它接受两个参数(prev,current)。prev参数与种子类型相同,current参数与上游参数类型相同

例子 注 您必须在每次#扫描迭代中复制一份列表,或者使用来自持久数据收集的不可变列表


此外,这可能不是一个好的实现,因为列表是未绑定的,这可能会占用您所有的内存。如果列表足够大,线性搜索也可能需要一些时间,这可能不太好。您应该考虑如何更好地执行循环。

非常感谢您的见解!我还为列表的长度,并考虑使用某种缓存的主题/生产者,一旦我向用户显示所有排队的项目都已发送,我就不再需要当前的队列历史记录。
class So65587608 {
    @Test
    fun `65587608`() {
        val producer = PublishSubject.create<QueuedItem>()

        val map = producer.scan(mutableListOf<QueuedItem>(), { list, curr ->
            // when send = true -> remove
            if (curr.sent) {
                list.removeIf { it.item == curr.item }
            } else if (!list.any { it.item == curr.item }) {
                list.add(curr)
            }
            list.toMutableList()
        }).map { list -> list as List<QueuedItem> }

        map.subscribe {
            println(it)
        }

        val test = map.test()

        producer.onNext(QueuedItem("1"))
        producer.onNext(QueuedItem("1", true))
        producer.onNext(QueuedItem("2", true))
        producer.onNext(QueuedItem("3", true))
        producer.onNext(QueuedItem("4"))
        producer.onNext(QueuedItem("5"))
        producer.onNext(QueuedItem("4", true))
    }

    data class QueuedItem(val item: String, val sent: Boolean = false)
}
[] // seed value
[QueuedItem(item=1, sent=false)]
[]
[]
[]
[QueuedItem(item=4, sent=false)]
[QueuedItem(item=4, sent=false), QueuedItem(item=5, sent=false)]
[QueuedItem(item=5, sent=false)]