当我们拥有以下一种数组

const preson = [
    { name: 'zhangsan', age: 18, sex: "female"},
    { name: 'lisi', age: 19, sex: "female"},
    { name: 'wangwu', age: 30, sex: "male" },
    { name: 'Alice', age: 40, sex: "male" },
    { name: 'Broky', age: 30, sex: "female" },
    { name: 'Rain', age: 35, sex: "female" },
    { name: 'Niko', age: 32, sex: "female" },
    { name: 'donk', age: 18, sex: "female" },
    { name: 'Eva', age: 40, sex: "male" },
    { name: 'Frank', age: 28, sex: "female" },
    { name: 'wangsan', age: 38, sex: "male" },
    { name: 'Grace', age: 48, sex: "male" },
    { name: 'lili', age: 58, sex: "male"},
]

如果想要按照某个属性分类,比如说性别,那么方法非常简单,如下

const result = {};
for (let i = 0; i < preson.length; i++) {
    const item = preson[i];
    const key = item.sex;
    if (!result[key]) {
        result[key] = [];
    }
    result[key].push(item);
}

我们就可以快速拿到结果

以此类推,要想拿到其他分组,我们只需要改变key值就可以,那么就可以写一个通用性函数

function groupBy(arr, prop) {
    const result = {};
    for (let i = 0; i < arr.length; i++) {
        const item = arr[i];
        const key = item[prop];
        if (!result[key]) {
            result[key] = [];
        }
        result[key].push(item);
    }
    console.log(result);
}
groupBy(preson, 'sex');

将数组和分类属性作为参数传入,那么这段代码就具备一定的通用性了,但是还是不够完美,如果我们是其他数组呢,数字数组,组合分组,那么这个函数的通用性其实是不够的,所以还需要优化,我们再看一下上面这个函数,去思考一下,哪些参数是关键的,用于分组的键。

item[prop]

因此需要传递一个函数

function groupBy(arr, generateKey) {
    const result = {};
    for (let i = 0; i < arr.length; i++) {
        const item = arr[i];
        const key = generateKey(item, i, arr);
        if (!result[key]) {
            result[key] = [];
        }
        result[key].push(item);
    }
    return result;
}
const result1 = groupBy(preson, (p) => p.sex);
console.log(result1);

那么这个函数就具备通用性了,比如年龄和性别分组

我们还可以对函数进行归一化

function groupBy(arr, generateKey) {
    if(typeof generateKey === 'string') {
        const key = generateKey;
        generateKey = (item) => item[key];
    }
    const result = {};
    for (let i = 0; i < arr.length; i++) {
        const item = arr[i];
        const key = generateKey(item, i, arr);
        if (!result[key]) {
            result[key] = [];
        }
        result[key].push(item);
    }
    return result;
}
const result1 = groupBy(preson, "sex");

那么无论是函数还是属性值都可以识别