2016-09-20 9 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')); 

Скажем, я хочу обрабатывать группы по-разному на основе значение «а» этой группы:

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», выполняет ли арифметическую операцию на основе значения в один объект, содержащий свойства типа и 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()), возможно, является способом продвижения вперед. Но у вас есть условные проверки свойства «a» внутри .fold() ... видя, что вы уже сгруппировали groupStream на значение «a», кажется немного расточительным, чтобы затем проверить каждый объект в этих группах для значения of 'a'. Одной из вещей, которые люди торчат о потоках, является их эффективность. Конечно, один маленький чек не вызывает большого беспокойства, но меня это удивляет. – stephband

+0

Теперь представьте, что я хочу взять первый объект 1, где === 1, но первые 2 объекта, где === 2. .fold() на самом деле не помогают здесь, если только я не помещаю в него инкрементный счетчик var внутри. flatMap - на самом деле, мне понадобится счетчик var для каждого значения «a» (и я не знаю, сколько значений «a» есть). В идеале я хочу сделать, если (v.key === 1) {return v.take (1); } if (v.key === 2) {return v.take (2); } ... но нет такой вещи, как v.key ... – stephband

+0

Я добавил пример на вопрос, чтобы проиллюстрировать эту проблему. – stephband