2016-09-20 42 views
0

首先,我對流很陌生,所以我仍然在處理一些常見的模式。如何分組一個流,然後根據組的密鑰分別處理組?

在很多庫中,我們可以使用.groupBy(keySelectorFn)將一個流分成一串流。例如,該料流被分成基於的「A」中的每個對象的值流(僞代碼中,不基於任何特定的庫):

var groups = Stream.of(
    { a: 1, b: 0 }, 
    { a: 1, b: 1 }, 
    { a: 2, b: 2 }, 
    { a: 1, b: 3 } 
) 
.groupBy(get('a')); 

說我希望基於所述以不同方式處理基該組的「A」的值:

groups.map(function(group) { 
    if (..?) { 
     // Run the group through some process 
    } 

    return group; 
}); 

我看不出怎麼弄的「A」,而無需耗費每個組的第一個元素(如果一個組的第一個元素被消耗的值組不再完整)。

在我看來,這似乎是我想用流處理的一個相當常見的事情。我採取了錯誤的做法嗎?

---編輯---

這裏有一個問題的更具體的例子,我卡上:

var groups = Stream.of(
    { a: 1, b: 0 }, 
    { a: 1, b: 1 }, 
    { a: 2, b: 0 }, 
    { a: 2, b: 1 }, 
    { a: 2, b: 2 }, 
    { a: 1, b: 2 } 
) 
.groupBy(get('a')); 

如何選擇第1名對象,其中一個=== 1 ,以及前2個對象,其中=== 2,並通過任何其他對象直通?這似乎對我來說是合乎邏輯的:

groups.chain(function(group) { 
    return group.key === 1 ? 
     group.take(1) : 
    group.key === 2 ? 
     group.take(2) : 
     group ; 
}); 

但是group.key不存在(即使它看起來有點......臭)。

+0

你在尋找類似的東西嗎?:http://jsbin.com/haliqerita/edit?js,console –

回答

0

groupBy將爲您提供一串流(流中的每個值都是流本身)。使用fold,你可以將每個組(這是一個流)處理成一個值(使用條件)。 flatMap將所有結果放入單個流中。這是一個處理對象組的簡單例子。它根據屬性「a」對對象進行分組,根據值對一個包含type和val屬性的單個對象進行算術運算。這些最終對象壓扁成一個單一的數據流:

 
var groupStream = Bacon.fromArray([ 
    { a: 1, b: 0 }, 
    { a: 1, b: 1 }, 
    { a: 2, b: 2 }, 
    { a: 1, b: 3 } 
]); 

// -----[stream of objects where a=1]-------[stream of objects where a=2]----> 
var groups = groupStream.groupBy(function(k){ return k.a; }) 

// v is a stream of a=1 objects or a=2 objects 
groups.flatMap(function(v) { 

//fold(reduce) over the values in v (stream) 
    return v.fold({type:'', val: 0},function(acc,i) { 
    if(i.a == 1) { 
     return {type: 'one', val: acc.val + i.b }; 
    } 

    if(i.a == 2) { 
     return {type: 'two', val: acc.val + i.b }; 
    } 
    }) 
}).onValue(function(v) { 
    console.log(v); 
}); 

這裏是jsbin:http://jsbin.com/haliqerita/edit?js,console

希望有所幫助。

+0

好的,好的。我可以看到使用.fold()(或.reduce())可能是前進的方向。但是你在.fold()裏面有屬性'a'的條件檢查......因爲你已經把groupStream用'a'的值分組了,看起來有點浪費,於是必須檢查這些組中的每個對象的值'a'。人們對小溪的吹噓之一就是它們的效率。當然,一張小票不是一個大問題,但我對這種事情感到驚訝。 – stephband

+0

現在想象一下,如果我想在第一個對象中取一個=== 1,但前兩個對象其中一個=== 2. .fold()在這裏沒有真正的幫助,除非我在其中放置了一些可增量的計數器var。 flatMap - 實際上,我需要一個計數器變量來表示'a'的每個值(我可能不知道有多少個'a'值)。理想情況下,我想如果(v.key === 1){return v.take(1); } if(v.key === 2){return v.take(2); } ...但是沒有v.key這樣的東西... – stephband

+0

我在問題中增加了一個例子來說明這個問題。 – stephband