使用Rx运行直方图流

9
我有以下单字母流。
A 
B 
C 
A
D 
B 
A 
C 
D

从这个流中,我想要一个按字母计数的运行总数流。

(A,1)
(A,1), (B,1)
(A,1), (B,1), (C,1)
(A,2), (B,1), (C,1)
(A,2), (B,1), (C,1), (D,1)
(A,2), (B,2), (C,1), (D,1)
(A,3), (B,2), (C,1), (D,1)     
(A,3), (B,2), (C,2), (D,1) 
(A,3), (B,2), (C,2), (D,2)     

即每输入一个新字母,总数都会更新并发出。

我想这个问题与语言无关,所以请随意提出你喜欢的语言的解决方案。

2个回答

12

这是使用 RxJava 完成的方法:

final Observable<String> observable = Observable.just("A", "B", "C", "A", "D", "B", "A", "C", "D");
final Observable<LinkedHashMap<String, Integer>> histogram = observable.scan(new LinkedHashMap<>(), (state, value) -> {
  if (state.containsKey(value)) {
    state.put(value, state.get(value) + 1);
  } else {
    state.put(value, 1);
  }

  return state;
});

histogram.subscribe(state -> {
  System.out.println(state);
});

输出:

{}
{A=1}
{A=1, B=1}
{A=1, B=1, C=1}
{A=2, B=1, C=1}
{A=2, B=1, C=1, D=1}
{A=2, B=2, C=1, D=1}
{A=3, B=2, C=1, D=1}
{A=3, B=2, C=2, D=1}
{A=3, B=2, C=2, D=2}

1
在RxJS中,它可能是这样的:

RxJS

var letters   = Rx.Observable.of('A', 'B', 'C', 'A', 'D', 'B', 'A', 'C', 'D'),
    histogram = letters.scan(countL, Object.create(null));

histogram.subscribe(console.log.bind(console));

function countL(ls, l) {
    if (!ls[l]) ls[l] = 0;
    ls[l]++;
    return ls;
}

如果您不希望下游观察者在不经意间更改其结果,请使用immutable map - Brandon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接