2015-09-29 12 views
9

ho il seguente flusso lettera singolaesecuzione con Rx

A 
B 
C 
A 
D 
B 
A 
C 
D 

E da questo flusso, vorrei un flusso di conteggio parziale per lettera

(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)  

, cioè ad ogni nuova lettera , i totali vengono aggiornati ed emessi.

Immagino che questo problema sia abbastanza indipendente dal linguaggio, quindi non esitate a proporre una soluzione nella vostra lingua preferita.

risposta

11

Ecco come può essere fatto utilizzando 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); 
}); 

uscita:

{} 
{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

In RxJS potrebbe essere qualcosa di simile:

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; 
} 
+0

o usare un [mappa immutabili ] (https://facebook.github.io/immutable-js/docs/#/Map) se non si desidera che gli osservatori a valle abbiano la loro Gli ults sono cambiati da sotto di loro inavvertitamente. – Brandon