const people = [
{ name: 'Alice', age: 30, sex: 'female' },
{ name: 'Bob', age: 25, sex: 'male' },
{ name: 'Charlie', age: 30, sex: 'male' },
{ name: 'Diana', age: 25, sex: 'female' },
{ name: 'Eva', age: 25, sex: 'female' },
{ name: 'Frank', age: 25, sex: 'male' },
{ name: 'Grace', age: 2, sex: 'female' },
];
按年龄分组
const result = {};
for (const item of people) {
const key = item.age;
if (!result[key]) {
result[key] = [];
}
result[key].push(item);
}
按照性别分组
const result = {};
for (const item of people) {
const key = item.sex;
if (!result[key]) {
result[key] = [];
}
result[key].push(item);
}
业务不同时,有可能会按照不同属性分组,这是我们发现只不过是key不同,此时我们可以写一个通用方法:
function groupBy(arr, propName) {
const result = {};
for (const item of arr) {
const key = item[propName];
if (!result[key]) {
result[key] = [];
}
result[key].push(item);
}
console.log('result', result);
return result;
}
这样按照年龄 或者性别就可以这么写了:
// 按年龄分组
groupBy(people, 'age');
// 按照性别分组
groupBy(people, 'sex');
但是有可能people数组也有可能是这样的(包含一个嵌套的对象)
const people = [
{ name: 'Alice', age: 30, sex: 'female' },
{ name: 'Bob', age: 25, sex: 'male' },
{ name: 'Charlie', age: 30, sex: 'male' },
{ name: 'Diana', age: 25, sex: 'female' },
{ name: 'Eva', age: 25, sex: 'female' },
{ name: 'Frank', age: 25, sex: 'male' },
{
name: 'Grace',
age: 20,
sex: 'female',
address: {
province: '黑龙江',
city: '哈尔滨',
},
},
];
此时我们可能想按照省份来分组,也有可能按照年龄+性别(20+female:[…])的方式来分组 发现上面的groupBy并不能实现
比如是一个数字数组,按照奇数偶数分组这个方法也不能实现
const num=[1,2,5,10,33]
此时我们发现不通用的原因主要在groupBy方法中key值的获取,groupBy的第二个函数应该为一个函数,由调用者自行来决定应该以什么样的东西来得到这个key值:
function groupBy(arr, generateKey) {
const result = {};
for (const item of arr) {
const key = generateKey(item);
if (!result[key]) {
result[key] = [];
}
result[key].push(item);
}
console.log('result', result);
return result;
}
这样年龄 或者性别就可以这样写了,得到的结果也是没问题的
groupBy(people, (item) => item.age);
groupBy(people, (item) => item.sex);
按年龄-性别分组:
groupBy(people, (item) => `${item.age}-${item.sex}`);
按照奇数偶数分组
const arr = [34, 6, 323, 2, 1, 5];
groupBy(arr, (item) => (item % 2 === 0 ? '偶' : '奇'));
我们希望groupBy方法他支持两种方式来传递第二个参数:一种是原来的属性名,另一种是函数,其实属性名是传递函数的一种特殊方式而已,只不过传递属性名会看着舒服一点,此时我们需要把groupBy 方法参数归一化:把不同的参数类型归纳成一种类型,这样方法会变的更通用,同时调用也简单
function groupBy(arr, generateKey) {
if (typeof generateKey === 'string') {
const propName = generateKey;
generateKey = (item) => item[propName];
}
const result = {};
for (const item of arr) {
const key = generateKey(item);
if (!result[key]) {
result[key] = [];
}
result[key].push(item);
}
console.log('result', result);
return result;
}