对数组进行分类:array.groupBy


假设我们有一个员工列表,其中每个员工都是一个具有 2 个属性的对象:name 和 age。

const people = [  
  { name: 'Alice', age: 21 },  
  { name: 'Max', age: 20 },  
  { name: 'Jane', age: 20 }  
];  

现在,我们需要对其进行按 age 分类,最终实现输出结果如下:

const groupedPeople = {  
  20: [  
    { name: 'Max', age: 20 },  
    { name: 'Jane', age: 20 }  
  ],  
  21: [  
    { name: 'Alice', age: 21 }  
  ]  
}  

通常的方法是使用 array.reduce(),reduce() 方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行
reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。鉴于此,可以借其实现一个 groupBy 函数:

function groupBy(objectArray, property) {  
  return objectArray.reduce(function (acc, obj) {  
    let key = obj[property]  
    if (!acc[key]) {  
      acc[key] = []  
    }  
    acc[key].push(obj)  
    return acc  
  }, {})  
}  
  
const groupedPeople = groupBy(people, 'age')  
// groupedPeople is:  
// {  
//   20: [  
//     { name: 'Max', age: 20 },  
//     { name: 'Jane', age: 20 }  
//   ],  
//   21: [  
//    { name: 'Alice', age: 21 }  
//   ]  
// }  

为了简化我们的代码,数组又提供了一个新的方法来对数组按属性进行分类:Array.prototype.groupBy()。

const groupedPeople = people.groupBy(({ age }) => age)  
// groupedPeople is:  
// {  
//   20: [  
//     { name: 'Max', age: 20 },  
//     { name: 'Jane', age: 20 }  
//   ],  
//   21: [  
//    { name: 'Alice', age: 21 }  
//   ]  
// }  

同时也支持按条件自定义分类:

const groupedPeople = people.groupBy(({ age }) => age <= 20? 'a': 'b')  
// groupedPeople is:  
// {  
//   'a': [  
//     { name: 'Max', age: 20 },  
//     { name: 'Jane', age: 20 }  
//   ],  
//   'b': [  
//    { name: 'Alice', age: 21 }  
//   ]  
// }  

如果需要对数组按属性分类,欢迎使用新的数组方法。