返回

JS 实现通过某个属性值对【对象数组】进行分组

前端

在项目开发中,调用接口请求数据时,后台返回的列表数据格式没按某一控制条件进行分组时,需要我们自己对数据重新进行处理,从而获得我们想要的数据结构。

使用场景

我们先来看一个使用场景,比如有一个对象数组,对象数组中的对象有以下属性:

const data = [
  {
    id: 1,
    name: 'John',
    age: 20,
    city: 'New York'
  },
  {
    id: 2,
    name: 'Jane',
    age: 25,
    city: 'London'
  },
  {
    id: 3,
    name: 'Tom',
    age: 30,
    city: 'Paris'
  },
  {
    id: 4,
    name: 'Mary',
    age: 28,
    city: 'Tokyo'
  },
  {
    id: 5,
    name: 'Bob',
    age: 32,
    city: 'Beijing'
  }
];

现在我们想按 city 属性对这个数组进行分组,以便我们可以轻松地访问每个城市中的人员列表。

实现方法

我们可以使用 reduce() 方法来实现分组。reduce() 方法会将数组中的每个元素逐个传递给一个回调函数,并返回一个累积值。在这个例子中,我们将 reduce() 方法的回调函数定义如下:

const groupByCity = (accumulator, currentValue) => {
  // 如果累积器中不存在当前值的城市属性值,则创建一个新的数组。
  if (!accumulator[currentValue.city]) {
    accumulator[currentValue.city] = [];
  }

  // 将当前值添加到该城市对应的数组中。
  accumulator[currentValue.city].push(currentValue);

  // 返回累积器。
  return accumulator;
};

然后,我们可以使用 reduce() 方法来对数组进行分组:

const groupedData = data.reduce(groupByCity, {});

groupedData 变量现在是一个对象,其键是城市名称,值是每个城市中人员的数组。

console.log(groupedData);
// 输出:
// {
//   'New York': [
//     {
//       id: 1,
//       name: 'John',
//       age: 20,
//       city: 'New York'
//     }
//   ],
//   'London': [
//     {
//       id: 2,
//       name: 'Jane',
//       age: 25,
//       city: 'London'
//     }
//   ],
//   'Paris': [
//     {
//       id: 3,
//       name: 'Tom',
//       age: 30,
//       city: 'Paris'
//     }
//   ],
//   'Tokyo': [
//     {
//       id: 4,
//       name: 'Mary',
//       age: 28,
//       city: 'Tokyo'
//     }
//   ],
//   'Beijing': [
//     {
//       id: 5,
//       name: 'Bob',
//       age: 32,
//       city: 'Beijing'
//     }
//   ]
// }

总结

使用 reduce() 方法可以轻松地对对象数组进行分组。这在需要按某个属性值对数据进行组织和分类时非常有用。