封装一个函数,可以根据下面数据以 某一项 分组
const person = [
{ name: "张三", age: 23, sex: "男" },
{ name: "李四", age: 23, sex: "男" },
{ name: "王五", age: 25, sex: "女" },
{ name: "赵六", age: 23, sex: "男" },
{ name: "钱七", age: 27, sex: "女" },
{ name: "孙八", age: 27, sex: "男" },
{ name: "周九", age: 29, sex: "女" },
{ name: "吴十", age: 23, sex: "女" },
{ name: "郑十一", age: 31, sex: "男" },
{ name: "王十二", age: 31, sex: "男" },
{ name: "李十三", age: 33, sex: "女" },
{ name: "张十四", age: 31, sex: "男" },
{ name: "李十五", age: 33, sex: "男" },
]
function groupBy(arr, propName) {
const result = {}
for (const ele of arr) {
const key = ele[propName]
if (!result[key]) {
result[key] = [ele]
}
result[key].push(ele)
}
return result
}
groupBy(person, 'sex')
groupBy(person, 'age')
此时通用性不够强大,例如增加需求:key为 「年龄-性别」、数据中每个对象有个属性address也为对象并根据address中的city进行分组。
将 groupBy
的参数变为函数,此时 groupBy
就变成了高阶函数,对key的获取也更加灵活。
function groupBy(arr, generateKey) {
const result = {}
for (const ele of arr) {
const key = generateKey(ele)
if (!result[key]) {
result[key] = [ele]
} else {
result[key].push(ele)
}
}
return result
}
groupBy(person, item => item.sex)
groupBy(person, item => item.age)
groupBy(person, item => `${item.age}-${item.sex}`)
// 奇偶数分组
groupBy([1, 4, 12, 3, 5], item => item % 2 === 0 ? '偶数' : '奇数')
继续优化,对于只针对某属性分组,如何仍然通过groupBy(person, 'sex')
这种简单方式调用,需要使用 参数归一化
思想,在函数内部将传入的字符串也转为函数写法,具体可看本人另一篇文章参数归一化。
function groupBy(arr, generateKey) {
if (typeof generateKey === 'string') {
let key = generateKey
generateKey = (item) => item[key]
}
const result = {}
for (const ele of arr) {
const key = generateKey(ele)
if (!result[key]) {
result[key] = [ele]
} else {
result[key].push(ele)
}
}
return result
}
groupBy(person, 'sex')
groupBy(person, 'age')
groupBy(person, item => `${item.age}-${item.sex}`)
// 奇偶数分组
groupBy([1, 4, 12, 3, 5], item => item % 2 === 0 ? '偶数' : '奇数')