2016-09-30 61 views
0

我有缓冲分组可观测量

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' } 
]; 

我想创建可观察到的,通过name对待HEROES阵列作为源,组阵列和下面的类和阵列发射的结果作为一个单一的阵列,即,我应该得到三个阵列,一个用于Narco,一个用于Bombasto,另一个用于Dynama

我可以创建源观察到如下

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

我然后可以使用groupBy,即一群英雄,

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

这实际上给了我许多可观,因为有不同的名称我的HEROES阵列(在这种情况下是三个)。但是,这些将作为序列发出,理想情况下我希望buffer直到heroSource完成。我如何在我的分组观察值中使用rxjs中的buffer运算符,以便发出单个集合?

回答

3

首先,你可以创建你的初始观察到的要简单得多:

var heroSource = Observable.from(HEROES); 

接下来,你GROUPBY映射器/选择器可以缩写为:

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是不标准的,你将不得不迭代键来得到一个数组,但它可能更适合你的需要