仅过滤,区分,将对象数组转换为对象序列并仅使用RXJS返回对象集合数组的处理

时间:2018-12-27 09:39:03

标签: angular rxjs rxjs6

我有替代解决方案,但它更像是在删除重复对象,过滤对象和转换对象数组时使用更多的非rxjs函数。

当那里有150到500条记录时,这会影响性能。

这里是代码的一瞥

打字稿模型

export class columns {
    public displayName: string;
    public fieldName: string;
    public tabName: string;
    public tabOrder: string;
}

然后是行为主题,用于从应用程序的各个部分传输或列出列数组。

public columnsNotify: BehaviorSubject<columns[]> = new BehaviorSubject([]);

一些样本数据

let listOfCols= [
    {displayName:"student name",fieldName:"stdName",tabName:"List",tabOrder:1},
    {displayName:"student id",fieldName:"stdid",tabName:"List",tabOrder:1},
    .....
    {displayName:"student name",fieldName:"stdName",tabName:"Details",tabOrder:2}
    {displayName:"student id",fieldName:"stdid",tabName:"Details",tabOrder:2}


];

this.columnsNotify.next(listOfCols);

现在是当前解决方案,我为 获取具有不同且按顺序排序的标签列表 而实现。

this.columnsNotify.pipe(
            map((column: columns[]) =>
                Array.from(
                    new Set(
                        column.map(mp => {
                            const obj = JSON.stringify({
                                tabName: mp.tabName,
                                tabOrder: mp.tabOrder
                            } as TabsInfo);

                            return obj;
                        })
                    )
                )
                    .map(data => JSON.parse(data))
                    .sort((a: TabsInfo, b: TabsInfo) => {
                        return a.tabOrder > b.tabOrder ? 1 : 0;
                    })
            )
        );

我试图通过展平数组来改善上述代码,但由于它等待可观察到的完成而被困于toArray运算符。

 this.columnsNotify.pipe(
        flatMap(searchCol => searchCol),
        map(
            (column: columns) =>
                new TabsInfo(column.tabName, column.tabOrder)
        ),
        distinct((tab: TabsInfo) => tab.tabName),
        take(3), //<-- Don't want this as, i don't know how many item there.
        toArray()  
    );

因此,是否仍然没有在toArray中使用take运算符, 否则这将是完全不同的新方法。

我需要在另一个地方使用类似的解决方案,在* ngFor中将使用可处理的可观察值,到目前为止,目前还没有运气n正在使用其他替代方法。

2 个答案:

答案 0 :(得分:2)

toArray()是您想要的运算符,但您遇到的问题是:flatMap(searchCol => searchCol),

这是您的解决方案,可以编写如下内容:

const expand = (items: columns[]) =>
  from(items).pipe(
    map((column: columns) => new TabsInfo(column.tabName, column.tabOrder)),
    distinct((tab: TabsInfo) => tab.tabName),
    toArray(),
  );

this.columnsNotify.pipe(
  switchMap((searchCol) => expand(searchCol)),
  tap((x) => console.log(x)),
);

请使用更新的RxJS中的switchMap()运算符,而不要使用flatMap()。 顺便说一下,mergeMap()flatMap()的新名称,但是在这种情况下,switchMap()更好。

如果我理解正确,请对它进行数字测试,然后按需要运行。

答案 1 :(得分:0)

您好,不确定为什么不能这样做:

const obs$ = of(listOfCols);

obs$.pipe(
  flatMap(t => t),
  map(t => {return new TabsInfo(t.tabName, t.tabOrder)}),
  distinct((tab: TabsInfo) => tab.tabName),
  toArray(),
  map( array => array.sort())
  ).subscribe( // of course if you want to us it in *ngFor remove subscribe.
    t => console.log(t)
  )

我认为我缺少了一些东西。