RxJS 6过滤和映射可观察项目数组

Jan*_*sen 1 rxjs angular

在带有RxJS 6.3.3的Angular 7.1.1应用程序中,应将可观察到的计划阵列转换为可观察到的活动计划卡阵列。主动过滤器为:

filter(plan => plan.is_active)
Run Code Online (Sandbox Code Playgroud)

从计划到卡片的转换是:

map(plan => new PlanCard(plan, 1, 1))
Run Code Online (Sandbox Code Playgroud)

因此,大概,答案是这样的:

plans: Observable<Plan[]> = getPlans();

cards: Observable<PlanCard[]> = plans.pipe(
  mergeAll(),
  filter(plan => plan.is_active),
  map(plan => new PlanCard(plan, 1, 1)),
  toArray()
);
Run Code Online (Sandbox Code Playgroud)

但是a,cards是空的。

可以通过以下方式将计划正确转换为卡片:

cards: Observable<PlanCard[]> = plans.pipe(
  map(plans => plans.map(plan => new PlanCard(plan, 1, 1)))
);
Run Code Online (Sandbox Code Playgroud)

但不幸的是,事先添加过滤器不会过滤计划:

cards: Observable<PlanCard[]> = plans.pipe(
  filter(plans => plans.filter(plan => plan.is_active)),
  map(plans => plans.map(plan => new PlanCard(plan, 1, 1)))
);
Run Code Online (Sandbox Code Playgroud)

还有更好的主意吗?

export const planData: Plan[] = [{
  name: 'P1',
  is_active: true
}, {
  name: 'P2',
  is_active: true
}, {
  name: 'P3',
  is_active: true
}, {
  name: 'P4',
  is_active: true
}, {
  name: 'P5',
  is_active: false
}];

export const plans = createObservable(planData);
Run Code Online (Sandbox Code Playgroud)

Adr*_*and 7

mergeAll合并一个可观察对象。

你要

cards: Observable<PlanCard[]> = plans.pipe(
  map(plans => plans.filter(plan => plan.is_active)), // An array comes down the pipe, you don't want to filter out the arrays but the elements in the array
  map(plans => plans.map(plan => new PlanCard(plan, 1, 1))), // An array of active plans can be mapped into an array of PlanCards
  reduce((results, plans) => [...results, ...plans], []) // Reduce all the arrays into a single array
);
Run Code Online (Sandbox Code Playgroud)

如果您希望reduce的累加器在每次新阵列发生故障时都下降,您可以使用scan而不是reduce,仅在所有阵列下降之后才进行reduce。

我通常不会在地图后面使用过滤器,但是更容易了解发生了什么,我通常会一步一步地完成操作,并进行归约,

plans => plans.reduce((results, plan) => plan.is_active ? [...results, new PlanCard(plan, 1, 1)] : results, [])
Run Code Online (Sandbox Code Playgroud)

与后跟贴图的过滤器相同,但一次迭代而不是两次迭代。

当您拥有数组的可观察对象时,您需要考虑要对观察对象应用哪些函数以及要对管道中的数组应用哪些函数,这可能会造成混乱。

cards: Observable<PlanCard[]> = plans.pipe(
  map(plans => plans.filter(plan => plan.is_active)), // An array comes down the pipe, you don't want to filter out the arrays but the elements in the array
  map(plans => plans.map(plan => new PlanCard(plan, 1, 1))), // An array of active plans can be mapped into an array of PlanCards
  reduce((results, plans) => [...results, ...plans], []) // Reduce all the arrays into a single array
);
Run Code Online (Sandbox Code Playgroud)
plans => plans.reduce((results, plan) => plan.is_active ? [...results, new PlanCard(plan, 1, 1)] : results, [])
Run Code Online (Sandbox Code Playgroud)