Angular 5中按多字段分组数组并重组宠物数据的实现方案
嘿,我帮你捋捋这个问题!你需要把重复的人员条目合并,按宠物类型分别整理成cats和dogs数组,然后在Angular 5的表格里展示,对吧?其实用JavaScript的reduce方法就能很简洁地搞定这个数据转换,比你之前用Map的方式更直接,还不用额外做Map转数组的操作。
第一步:数据转换核心代码
直接用reduce遍历原始数组,按name+surname分组,把宠物归类到对应的数组里:
// 你的原始API返回数据 const rawPeople = [ { name: 'John', surname: 'Doe', pet: { type: 'CAT', name: 'whiskers', age: 1 } }, { name: 'John', surname: 'Doe', pet: { type: 'DOG', name: 'Dexter', age: 4 } }, { name: 'Jane', surname: 'Doe', pet: { type: 'CAT', name: 'Fluffy', age: 10 } }, { name: 'Jane', surname: 'Doe', pet: { type: 'CAT', name: 'Dennis', age: 3 } } ]; // 转换为目标结构 const transformedPeople = rawPeople.reduce((acc, current) => { // 生成唯一分组键 const key = `${current.name}_${current.surname}`; // 查找当前分组是否已存在 let existingPerson = acc.find(p => `${p.name}_${p.surname}` === key); if (!existingPerson) { // 不存在则创建新的人员对象,初始化空的cats和dogs数组 existingPerson = { name: current.name, surname: current.surname, cats: [], dogs: [] }; acc.push(existingPerson); } // 根据宠物类型添加到对应数组 const petData = { name: current.pet.name, age: current.pet.age }; if (current.pet.type === 'CAT') { existingPerson.cats.push(petData); } else if (current.pet.type === 'DOG') { existingPerson.dogs.push(petData); } return acc; }, [] as Array<{ name: string; surname: string; cats: any[]; dogs: any[] }>);
第二步:适配你的Person和Pet类
如果你已经定义了Person和Pet类,只需要稍微调整代码,用类实例来创建对象:
// 假设你的类定义是这样的 class Person { name: string; surname: string; cats: Pet[]; dogs: Pet[]; constructor(name: string, surname: string) { this.name = name; this.surname = surname; this.cats = []; this.dogs = []; } } class Pet { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } } // 调整后的转换代码 const transformedPeople = rawPeople.reduce((acc, current) => { const key = `${current.name}_${current.surname}`; let existingPerson = acc.find(p => `${p.name}_${p.surname}` === key); if (!existingPerson) { existingPerson = new Person(current.name, current.surname); acc.push(existingPerson); } const newPet = new Pet(current.pet.name, current.pet.age); if (current.pet.type === 'CAT') { existingPerson.cats.push(newPet); } else { existingPerson.dogs.push(newPet); } return acc; }, [] as Person[]);
第三步:优化Angular模板展示
你原来的模板已经能用,但可以加个空状态提示,避免空列表显得突兀:
<table> <thead> <tr> <th>Name</th> <th>Surname</th> <th>Cats</th> <th>Dogs</th> </tr> </thead> <tbody> <tr *ngFor="let person of transformedPeople"> <td>{{person.name}}</td> <td>{{person.surname}}</td> <td> <ul *ngIf="person.cats.length > 0; else noCats"> <li *ngFor="let cat of person.cats">name: {{cat.name}}, age: {{cat.age}} years</li> </ul> <ng-template #noCats>None</ng-template> </td> <td> <ul *ngIf="person.dogs.length > 0; else noDogs"> <li *ngFor="let dog of person.dogs">name: {{dog.name}}, age: {{dog.age}} years</li> </ul> <ng-template #noDogs>None</ng-template> </td> </tr> </tbody> </table>
这个方案的好处是逻辑清晰,代码简洁,直接生成你需要的数组结构,完全满足前端处理的需求。
内容的提问来源于stack exchange,提问作者mobbs
相关产品推荐
相关产品推荐

