我们有一个数组对象,里面的内容,如下:
const arr = [
{ name: 'Jack', age: 20, sex: '男' },
{ name: 'Emily', age: 22, sex: '女' },
{ name: 'Michael', age: 23, sex: '女' },
{ name: 'Taylor', age: 25, sex: '男' },
{ name: 'Johnson', age: 20, sex: '男' },
{ name: 'William', age: 22, sex: '男' },
{ name: 'Elizabeth', age: 23, sex: '女' },
{ name: 'Andrew', age: 25, sex: '女' },
{ name: 'Wilson', age: 23, sex: '男' },
{ name: 'Andrew', age: 22, sex: '女' }
];
我们有个需求:按照年龄分组,年龄作为对象的键名,值为分类的数组
const groupBy=(arr)=>{
const newObj = {};
for (let i of arr) {
let key = i.age;
if (!newObj[key]) {
newObj[key] = [];
}
newObj[key].push(i);
}
console.log(newObj);
}
groupBy(arr)
打印的结果:
{
'20': [
{ name: 'Jack', age: 20, sex: '男' },
{ name: 'Johnson', age: 20, sex: '男' }
],
'22': [
{ name: 'Emily', age: 22, sex: '女' },
{ name: 'William', age: 22, sex: '男' },
{ name: 'Andrew', age: 22, sex: '女' }
],
'23': [
{ name: 'Michael', age: 23, sex: '女' },
{ name: 'Elizabeth', age: 23, sex: '女' },
{ name: 'Wilson', age: 23, sex: '男' }
],
'25': [
{ name: 'Taylor', age: 25, sex: '男' },
{ name: 'Andrew', age: 25, sex: '女' }
]
}
这样固定字段不太灵活,如果需求在一直变化,函数需要写很多个,可能下次需求以sex分组,代码做一次改进
const groupBy=(arr,propName)=>{
const newObj = {};
for (let i of arr) {
let key = i[propName];
if (!newObj[key]) {
newObj[key] = [];
}
newObj[key].push(i);
}
console.log(newObj);
}
groupBy(arr,'age')
groupBy(arr,'sex')
打印的结果:
//age分组
{
'20': [
{ name: 'Jack', age: 20, sex: '男' },
{ name: 'Johnson', age: 20, sex: '男' }
],
'22': [
{ name: 'Emily', age: 22, sex: '女' },
{ name: 'William', age: 22, sex: '男' },
{ name: 'Andrew', age: 22, sex: '女' }
],
'23': [
{ name: 'Michael', age: 23, sex: '女' },
{ name: 'Elizabeth', age: 23, sex: '女' },
{ name: 'Wilson', age: 23, sex: '男' }
],
'25': [
{ name: 'Taylor', age: 25, sex: '男' },
{ name: 'Andrew', age: 25, sex: '女' }
]
}
//sex分组
{
'男': [
{ name: 'Jack', age: 20, sex: '男' },
{ name: 'Taylor', age: 25, sex: '男' },
{ name: 'Johnson', age: 20, sex: '男' },
{ name: 'William', age: 22, sex: '男' },
{ name: 'Wilson', age: 23, sex: '男' }
],
'女': [
{ name: 'Emily', age: 22, sex: '女' },
{ name: 'Michael', age: 23, sex: '女' },
{ name: 'Elizabeth', age: 23, sex: '女' },
{ name: 'Andrew', age: 25, sex: '女' },
{ name: 'Andrew', age: 22, sex: '女' }
]
}
还可能遇到组合字段的分类,例如'25-男',上面方法就没法实现,就需要对代码进行进一步改进
const groupBy=(arr,propFn)=>{
const newObj = {};
for (let i of arr) {
let key = propFn(i);
if (!newObj[key]) {
newObj[key] = [];
}
newObj[key].push(i);
}
console.log(newObj);
}
groupBy(arr,item=>`${item.age}-${item.sex}`)
打印结果:
{
'20-男': [
{ name: 'Jack', age: 20, sex: '男' },
{ name: 'Johnson', age: 20, sex: '男' }
],
'22-女': [
{ name: 'Emily', age: 22, sex: '女' },
{ name: 'Andrew', age: 22, sex: '女' }
],
'23-女': [
{ name: 'Michael', age: 23, sex: '女' },
{ name: 'Elizabeth', age: 23, sex: '女' }
],
'25-男': [ { name: 'Taylor', age: 25, sex: '男' } ],
'22-男': [ { name: 'William', age: 22, sex: '男' } ],
'25-女': [ { name: 'Andrew', age: 25, sex: '女' } ],
'23-男': [ { name: 'Wilson', age: 23, sex: '男' } ]
}
虽然我们能够自定义了分组的条件,但是传值的类型始终受到限制,我们只能传方法,可是我们想要的是:传入的参数为方法,那么就按照定义的方法来分组,传的为值,那就按照传入的值来分组,无论我们传入的任何值,都会自动转换为方法,那按照这个思路,我们只需要将传入的值,或者方法,统一变为方法执行,那这个方法就会变得非常灵活了:
const groupBy=(arr,propFn)=>{
if(typeof propFn ==='string'){
const propsName=propFn
propFn=item=>item[propsName]
}
const newObj = {};
for (let i of arr) {
let key = propFn(i);
if (!newObj[key]) {
newObj[key] = [];
}
newObj[key].push(i);
}
console.log(newObj);
}