Вопросы полужирный ниже. Учитывая, что это мой компонент HTML UI:
<mat-tab label="Beginners">
<courses-card-list [courses]="coursesBeginners$ | async">
</courses-card-list>
</mat-tab>
<mat-tab label="Advanced">
<courses-card-list [courses]="coursesAdvanced$ | async">
</courses-card-list>
</mat-tab>
У меня есть курсы $ observable, которые мне нужно отфильтровать по нескольким наблюдаемым в зависимости от категории каждого курса. Для краткости я ограничу пример двумя категориями. Я использовал этот фрагмент в своем компоненте ts в приложении Angular 7:
this.beginnersCourses$ = this.courses$.pipe(
map(courses => courses.filter(
course => course.categories.includes("BEGINNER"))));
this.advancedCourses$ = this.courses$.pipe(
map(courses => courses.filter(
course => course.categories.includes("ADVANCED"))));
к этому:
let courses0: Course[] = [];
let courses1: Course[] = [];
courses$
.pipe(
map(courses => {
courses.forEach(course => {
if (course.categories.includes('BEGINNER')) {
courses0.push(course);
} else if (course.categories.includes('ADVANCED')) {
courses1.push(course);
}
});
}),
)
.subscribe(() => {
this.coursesBeginners$ = of(courses0);
this.coursesAdvanced$ = of(courses1);
});
Хотя вторая версия - больше кода, она более эффективна, потому что мы выполняем итерацию только один раз в коллекции курсов, а не столько раз, сколько есть категории. Кстати, можно ли сделать его еще короче?
Теперь, , я хотел бы написать еще более эффективный код, используя groupBy
, как указано здесь во втором примере на сайте learnrxjs, но у меня есть проблема с отображением моей проблемы в простой пример, показанный в примере - моя ценность - это целый объект курса, а не просто свойство. Я также попробовал подход, показанный здесь в документации по rxjs, но я не прошёл мимо функции reduce
без ошибок компиляции.
Я также понимаю, что может быть трудно разделить на основе метода includes
, в этом случае даже выбор значения course.categories[0]
будет удовлетворительным, если нет другого способа.
Спасибо!