我有一个包含数组的流,每个数组都有一个id。我需要将其拆分为每个id的流,当源流不再带有id时,它将完成。
E.g。输入具有这三个值的流序列
[{a:1}, {b:1}] [{a:2}, {b:2}, {c:1}] [{b:3}, {c:2}]
应返回三个流
a -> 1 2 |
b -> 1 2 3
c -> 1 2
如果a已经在第3个值上完成,因为它的id已经消失,并且已经在第2个值上创建了c,因为它的id已经出现。
我正在尝试groupByUntil,有点像
var input = foo.share();
var output = input.selectMany(function (s) {
return rx.Observable.fromArray(s);
}).groupByUntil(
function (s) { return s.keys()[0]; },
null,
function (g) { return input.filter(
function (s) { return !findkey(s, g.key); }
); }
)
因此,按ID分组,并在输入流不再具有id时处置该组。这似乎有效,但输入的两种用法看起来很奇怪,就像使用单个流控制groupByUntil的输入和处理组时可能存在奇怪的顺序依赖。
有更好的方法吗?
更新
这确实存在一个奇怪的时间问题。默认情况下,fromArray使用currentThread调度程序,这将导致来自该数组的事件与来自输入的事件交错。然后在错误的时间(在处理先前输入的组之前)评估组上的处置条件。
可能的解决方法是使用fromArray(..,rx.Scheduler.immediate),这将使分组事件与输入保持同步。
答案 0 :(得分:1)
var d = Object.create(null);
var output = input
.flatMap(function (s) {
// end completed groups
Object
.keys(d)
.filter(function (k) { return !findKey(s, k); })
.forEach(function (k) {
d[k].onNext(1);
d[k].onCompleted();
delete d[k];
});
return Rx.Observable.fromArray(s);
})
.groupByUntil(
function (s) { return s.keys()[0]; },
null,
function (g) { return d[g.key] = new Rx.AsyncSubject(); });