使用rxjs在Angular应用程序中对JSON数据进行分组



我需要有这样的形式的数据才能执行2个嵌套的ngFor循环:

this.groupedCities = [
{
label: 'Germany', value: 'de', 
items: [
{label: 'Berlin', value: 'Berlin'},
{label: 'Frankfurt', value: 'Frankfurt'},
{label: 'Hamburg', value: 'Hamburg'},
{label: 'Munich', value: 'Munich'}
]
},
{
label: 'USA', value: 'us', 
items: [
{label: 'Chicago', value: 'Chicago'},
{label: 'Los Angeles', value: 'Los Angeles'},
{label: 'New York', value: 'New York'},
{label: 'San Francisco', value: 'San Francisco'}
]
},
];

但我的后端只提供这样的:

this.data = [         
{label: 'Berlin', value: 'Berlin', country: 'Germany'},
{label: 'Frankfurt', value: 'Frankfurt', country: 'Germany'},
{label: 'Hamburg', value: 'Hamburg', country: 'Germany'},
{label: 'Munich', value: 'Munich', country: 'Germany'}
{label: 'Chicago', value: 'Chicago', country: 'USA'},
{label: 'Los Angeles', value: 'Los Angeles', country: 'USA'},
{label: 'New York', value: 'New York', country: 'USA'},
{label: 'San Francisco', value: 'San Francisco', country: 'USA'}
];

我似乎记得在rxjs中有一种方法可以做到这一点,但我记不起来了。

您可以通过这些RxJS运算符的组合来实现这一点

  1. 分组依据
  2. 合并映射
  3. 减少
  4. toArray
import { from } from 'rxjs'; 
import { groupBy, mergeMap, reduce, toArray } from 'rxjs/operators';
const mapper = {
'Germany': 'de',
'USA': 'us'
};
const data$ = from([
{label: 'Berlin', value: 'Berlin', country: 'Germany'},
{label: 'Frankfurt', value: 'Frankfurt', country: 'Germany'},
{label: 'Hamburg', value: 'Hamburg', country: 'Germany'},
{label: 'Munich', value: 'Munich', country: 'Germany'},
{label: 'Chicago', value: 'Chicago', country: 'USA'},
{label: 'Los Angeles', value: 'Los Angeles', country: 'USA'},
{label: 'New York', value: 'New York', country: 'USA'},
{label: 'San Francisco', value: 'San Francisco', country: 'USA'}
]);
const grouped$ = data$.pipe(
groupBy(city => city.country),
mergeMap(group => group
.pipe(
reduce((acc, cur) => {
const item = {label: cur.label, value: cur.value};
acc.items.push(item);
return acc;
},
{ key: group.key, value: mapper[group.key], items: [] }
)
)
),
toArray()
);
grouped$.subscribe(console.log);

演示:https://playcode.io/976662

希望这能有所帮助;我注意到国家代码没有缩写键

const partition = (arr, fn) =>
arr.reduce(
(acc, val, i, arr) => {
acc[fn(val, i, arr) ? 0 : 1].push(val);
return acc;
},
[[], []]
);
let data = [
{label: 'Berlin', value: 'Berlin', country: 'Germany'},
{label: 'Frankfurt', value: 'Frankfurt', country: 'Germany'},
{label: 'Hamburg', value: 'Hamburg', country: 'Germany'},
{label: 'Munich', value: 'Munich', country: 'Germany'},
{label: 'Chicago', value: 'Chicago', country: 'USA'},
{label: 'Los Angeles', value: 'Los Angeles', country: 'USA'},
{label: 'New York', value: 'New York', country: 'USA'},
{label: 'San Francisco', value: 'San Francisco', country: 'USA'}
];
const [germany, nonGermany] = partition(data, o=> o.country === 'Germany').map((arr) =>{
return arr.reduce((acc, cv, i) => {
if(i === 0){
acc = {...acc, label: cv.country, value: '', items: [{label: cv.label, value: cv.value}]}
return acc
}
return {
...acc,
items:[
...acc.items,
{label: cv.label, value: cv.value}
]
};
}, {})
});
console.log(germany);
console.log(nonGermany);

最新更新