Angular 处理方式,如过滤、区分、将对象数组转换为对象序列以及仅使用RXJS返回对象集合数组

Angular 处理方式,如过滤、区分、将对象数组转换为对象序列以及仅使用RXJS返回对象集合数组,angular,rxjs,rxjs6,Angular,Rxjs,Rxjs6,我有另一种解决方案,但它更像是在删除重复、过滤和转换对象数组的同时使用更多非rxjs函数 当有150到500条记录时,这会影响性能 这里有一些代码 类型脚本模型 export class columns { public displayName: string; public fieldName: string; public tabName: string; public tabOrder: string; } 然后是从应用程序的各个部分传输或列出列数组的行为

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

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

这里有一些代码

类型脚本模型

export class columns {
    public displayName: string;
    public fieldName: string;
    public tabName: string;
    public tabOrder: string;
}
然后是从应用程序的各个部分传输或列出列数组的行为主题

public columnsNotify: BehaviorSubject<columns[]> = new BehaviorSubject([]);
现在,我实现了当前的解决方案,用于获取选项卡列表,这些选项卡按顺序进行排序

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()  
    );
this.columnsotify.pipe(
平面图(searchCol=>searchCol),
地图(
(列:列)=>
新TabsInfo(column.tabName,column.tabOrder)
),
独特((tab:TabsInfo)=>tab.tabName),

以(3)为例,//嗨,我不知道你为什么不能这样做:

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)
  )
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)),
);
我想我遗漏了什么。

toArray()
是您需要的运算符,但您的问题在于:
flatMap(searchCol=>searchCol),

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

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)
  )
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()
更好


如果我理解正确,请在数字上测试它,并按照您的要求工作。

这很好,但有一点我不明白toArray如何知道observable是完整的。在您的情况下,observable不是完整的,而
toArray()
正在等待
complete()
信号,该信号未发生。在这种情况下,源可观测值切换到新的扩展可观测值,由于来自(项)
,该扩展可观测值将被完成。至于解释,
toArray()
实际上订阅了Observable,并将所有发出的值存储在数组中,当源代码完成时,它会发出结果数组。现在我明白了,谢谢