筛选 and/or 分组数据 Angular 5+
Filtering and/or grouping data in Angular 5+
不幸的是,我无法控制 API returns 数据。我得到我得到的:/
我需要帮助来正确格式化我的数据,或者可能使用自定义管道来正确显示它。我尝试过不同的东西(mergeMap、过滤器、按管道分组等),但我似乎无法得到我想要的东西。任何帮助将不胜感激。
示例数据
[
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
{ "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"},
...
]
组件
this.searchService.getData().subscribe(searchResults => {
this.searchResults = searchResults;
....? transform data here or custom pipe in template
});
期望的结果(显示名称一次,然后显示所有相关照片)
Bob Ross
Photo1
Photo2
Fred Rogers
Photo55
...
获得我正在寻找的输出的最有效方法是什么?提前致谢!
您可以使用 loadash 的 groupBy
和 toPairs
函数根据用户的名字和姓氏对数组数据进行分组,如下所示:-
var users = [
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
{ "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"}
]
var result = _.groupBy(users, (user)=> user.first + ' ' + user.last);
result = _.toPairs(result);
console.log('Result: ', result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
您可以根据上述功能格式化或创建您自己的自定义管道。
您可以参考以下 stackblitz 以查看可行的 Angular 解决方案。
以下代码是我的纯 RxJS 解决方案:P
import { from } from 'rxjs';
import { groupBy, mergeMap, map, toArray, tap } from 'rxjs/operators';
let searchResults = [
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
{ "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"}
];
from(this.searchResults).pipe(
// Select necessary attributes
map(result => {
//console.log('Result:', result);
let fname = result['first'];
let lname = result['last'];
let photo = result['photoTitle'];
let rname = [fname, lname].join(' ');
return { rname, photo };
}),
// group objects by `rname` attribute
groupBy(result => result['rname']),
// return each item in group as array
mergeMap(group => {
//console.log('Group :', group);
return group.pipe(
toArray(),
);
}),
// Reduce arrays of objects
map(group => {
//console.log('Group :', JSON.stringify(group));
let rname = group[0]['rname'];
return group.reduce((a, b) => {
return {
rname: rname,
photo: [a.photo, b.photo],
};
});
}),
// Bypass and verify results
tap(result => console.log('Result:', result)),
).subscribe();
不幸的是,我无法控制 API returns 数据。我得到我得到的:/
我需要帮助来正确格式化我的数据,或者可能使用自定义管道来正确显示它。我尝试过不同的东西(mergeMap、过滤器、按管道分组等),但我似乎无法得到我想要的东西。任何帮助将不胜感激。
示例数据
[
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
{ "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"},
...
]
组件
this.searchService.getData().subscribe(searchResults => {
this.searchResults = searchResults;
....? transform data here or custom pipe in template
});
期望的结果(显示名称一次,然后显示所有相关照片)
Bob Ross
Photo1
Photo2
Fred Rogers
Photo55
...
获得我正在寻找的输出的最有效方法是什么?提前致谢!
您可以使用 loadash 的 groupBy
和 toPairs
函数根据用户的名字和姓氏对数组数据进行分组,如下所示:-
var users = [
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
{ "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"}
]
var result = _.groupBy(users, (user)=> user.first + ' ' + user.last);
result = _.toPairs(result);
console.log('Result: ', result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
您可以根据上述功能格式化或创建您自己的自定义管道。
您可以参考以下 stackblitz 以查看可行的 Angular 解决方案。
以下代码是我的纯 RxJS 解决方案:P
import { from } from 'rxjs';
import { groupBy, mergeMap, map, toArray, tap } from 'rxjs/operators';
let searchResults = [
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo1.jpg", "photoTitle": "Photo1"},
{ "id": "rossbo01", "first": "Bob", "last": "Ross", "photo": "photo2.jpg", "photoTitle": "Photo2"},
{ "id": "rogersfr02", "first": "Fred", "last": "Rogers", "photo": "photo55.jpg", "photoTitle": "Photo55"}
];
from(this.searchResults).pipe(
// Select necessary attributes
map(result => {
//console.log('Result:', result);
let fname = result['first'];
let lname = result['last'];
let photo = result['photoTitle'];
let rname = [fname, lname].join(' ');
return { rname, photo };
}),
// group objects by `rname` attribute
groupBy(result => result['rname']),
// return each item in group as array
mergeMap(group => {
//console.log('Group :', group);
return group.pipe(
toArray(),
);
}),
// Reduce arrays of objects
map(group => {
//console.log('Group :', JSON.stringify(group));
let rname = group[0]['rname'];
return group.reduce((a, b) => {
return {
rname: rname,
photo: [a.photo, b.photo],
};
});
}),
// Bypass and verify results
tap(result => console.log('Result:', result)),
).subscribe();