2016-09-20 3 views
0

まず、私はストリームにはかなり新しいので、まだいくつかの共通パターンを把握しています。ストリームをグループ化し、グループのキーに基づいて別々にグループを処理するにはどうすればいいですか?

多くのライブラリでは、.groupBy(keySelectorFn)を使用してストリームをストリームのストリームに分割できます。例えば、このストリームが '各オブジェクト内の値に基づいて、ストリームに分割される(擬似コード、任意の特定のライブラリに基づいていない):

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; 
}); 

私は、各グループの最初の要素を消費することなく「」の値を取得する方法を見ることができない(グループの最初の要素が消費されている場合グループはもはや無傷ではない)。

これは私がストリームでやりたいことはかなり共通しているようです。私は間違ったアプローチをしていますか?

--- EDIT ---ここ

は私がこだわっている問題のより具体的な例を示します

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プロパティを含む単一のオブジェクトにします。これらの最後のオブジェクトは、単一のストリームにフラット化されていますhttp://jsbin.com/haliqerita/edit?js,console

希望に役立ちます:ここで

 
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です。

+0

右.fold()(または.reduce())を使用すると、おそらく前進する方法であることがわかります。しかし、あなたはすでにプロパティー 'a'を.fold()内で条件付きでチェックしています... groupStreamをすでに 'a'の値でグループ化しているのを見て、それらのグループ内の各オブジェクトを値'a'の人々が川を鳴らすことの1つは、効率性です。確かに、1つの小さな点検は大きな懸念ではありませんが、私はこの種の事に驚いています。 – stephband

+0

ここで、最初の1つのオブジェクトを=== 1のところに置いて、最初の2つのオブジェクト、つまり=== 2. .fold()は実際には役に立ちません。 flatMap - 実際には、 'a'の各値に対してカウンタのvarが必要です(そして、 'a'の値の数がわからない場合もあります)。理想的には、if(v.key === 1){return v.take(1); } if(v.key === 2){return v.take(2);} } ...しかし、v.keyのようなものはありません... – stephband

+0

私はその問題を説明するために質問に例を追加しました。 – stephband

関連する問題