楼主: eeeeeernt
68 0

高阶函数之-数据分组的思考 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

小学生

42%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
50 点
帖子
4
精华
0
在线时间
0 小时
注册时间
2018-7-6
最后登录
2018-7-6

楼主
eeeeeernt 发表于 2025-12-12 12:15:39 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
const people = [
  {name: 'ALice', age: 30, sex: 'female'},
  {name: 'BOb', age: 25, sex: 'male'},
  {name: 'Chartlie', 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'}
];

// 初始实现:按年龄分组
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);
}

这种重复编码显然不够高效。为此,可以封装一个通用的分组函数,使其支持动态指定分组依据。

// 封装基础分组函数
function groupBy(arr, propName) {
  const result = {};
  for (const item of arr) {
    const key = item[propName];
    if (!result[key]) {
      result[key] = [];
    }
    result[key].push(item);
  }
  return result;
}

// 使用示例
const result1 = groupBy(people, 'age');
const result2 = groupBy(people, 'sex');

虽然该函数已具备一定通用性,但面对更复杂的场景仍显不足。比如,数据结构中包含嵌套对象(如 address: {province: "河南", city: "开封"}),或需要基于多个字段组合分组,甚至根据数值奇偶性进行分类时,简单的属性名传参就无法满足需求了。

为提升灵活性,应将“键值生成”这一过程抽象成一个函数参数,从而让调用者自定义分组逻辑。

// 增强版分组函数:接受键值生成函数
function groupBy(arr, generateKey) {
  const result = {};
  for (const item of arr) {
    const key = generateKey(item);
    if (!result[key]) {
      result[key] = [];
    }
    result[key].push(item);
  }
  return result;
}

// 应用示例:
// 按年龄分组
const result1 = groupBy(people, (item) => item.age);

// 按性别分组
const result2 = groupBy(people, (item) => item.sex);

// 按年龄和性别联合分组
const result3 = groupBy(people, (item) => `${item.age}-${item.sex}`);

不仅如此,该模式还可拓展至非对象数组的场景。例如,处理数字数组并按奇偶性分组:

const arr = [34, 6, 321, 3, 5, 7];
const result4 = groupBy(arr, (item) => item % 2 === 0 ? '偶' : '奇');

通过将分组键的生成方式由固定属性访问升级为可配置函数,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);
  }
  return result;
}

接下来展示几种常见的调用场景:

按“年龄”字段进行分组:

const result1 = groupBy(people, 'age');

按“性别”字段进行分组:

const result2 = groupBy(people, 'sex');

按“年龄-性别”组合条件进行分组:

const result3 = groupBy(people, (item) => `${item.age}-${item.sex}`);

当处理的是数字数组时,也可根据特定规则进行分类。例如将数组元素按奇偶性分组:

const arr = [34, 6, 321, 3, 5, 7];
const result4 = groupBy(arr, (item) => item % 2 === 0 ? '偶' : '奇');

通过上述方式,无论传入的是字符串属性名还是自定义函数,都能被统一处理,提升了函数的灵活性与易用性。这种参数归一化的设计模式在工具函数开发中非常实用。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:数据分组 generate function province address

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-28 21:35