2016-09-30 1 views
0

У меня есть следующий класс и массивBuffer сгруппированных наблюдаемыми

class Hero { 
    id: number; 
    name: string; 
} 

const HEROES: Hero[] = [ 
    { id: 11, name: 'Narco' }, 
    { id: 12, name: 'Narco' }, 
    { id: 13, name: 'Bombasto' }, 
    { id: 14, name: 'Bombasto' }, 
    { id: 15, name: 'Bombasto' }, 
    { id: 16, name: 'Dynama' }, 
    { id: 17, name: 'Dynama' }, 
    { id: 18, name: 'Dynama' }, 
    { id: 19, name: 'Dynama' }, 
    { id: 20, name: 'Dynama' } 
]; 

Я хочу создать наблюдаемым, что лечит HEROES массив в качестве источника, группы массива по name и излучает результат в виде единого массива, т.е. , Я должен получить три массива, один для Narco, один для Bombasto и один для Dynama.

я могу создать свой источник наблюдаемого следующий

var heroSource = Observable.create((observer:any) => { 
      HEROES.forEach((hero: Hero) => { 
       observer.next(hero); 
      }) 
     }); 

Я могу тогда группа Heros с помощью groupBy, то есть,

var groupHeroSource = heroSource 
      .groupBy((hero: Hero) => {return hero.name}); 

Это фактически дает мне столько наблюдаемого, как есть разные имена мой массив HEROES (три в этом случае). Тем не менее, они будут выбрасываться как последовательность, и в идеале я бы хотел до buffer их до тех пор, пока heroSource не будет завершен. Как использовать оператор buffer в rxjs на моих сгруппированных наблюдаемых, чтобы испустить одну коллекцию?

ответ

3

Прежде всего, вы можете создать свой первоначальный наблюдаемую гораздо проще:

var heroSource = Observable.from(HEROES); 

Далее, ваш группиЙ картограф/селектор может быть сокращен до:

var groupHeroSource = heroSource.groupBy((hero: Hero): string => hero.name); 

Для решения исходной задачи мне нужно буферизуйте потоки, так как они готовы буфер со временем 0 будет выполнять работу (я думаю, там должно быть более элегантное решение там), используйте take (1), чтобы взять только первый результат (и избежать повторяющегося буфера) а затем слить все:

var finalGroup = groupHeroSource.map((ob) => ob.bufferWithTime(0).take(1)).mergeAll(); 

Обратите внимание, что с тех пор, так как ваш массив на самом деле статичен, поставив его через поток, а затем отображение не может быть самым простым решением, вы можете просто уменьшить его:

var grouped = HEROES.reduce((acc: any, hero: Hero) => { 
    acc[hero.name] = acc[hero.name] || []; 
    acc[hero.name].push(hero); 
    return acc; 
}, {}); 

С Object.values не является стандартным, вам придется перебирать ключи, чтобы получить массив, но он может быть лучше подходит для ваших нужд

 Смежные вопросы

  • Нет связанных вопросов^_^