You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:33:21