如何改编JavaScript代码为数组分组对象生成序列groupid?
给数组同值分组生成自增序列ID
没问题!这场景其实挺常见的,我来帮你实现给每个value分组生成自增groupid的需求~
核心实现思路
我们只需要一个计数器对象来跟踪每个value当前的序号,然后遍历数组时给每个元素对应分组的序号自增即可。这里推荐用map方法(不修改原数组,保持纯函数风格),代码非常简洁:
代码示例
let dataset = [ {value: "a"}, {value: "a"}, {value: "a"}, {value: "b"}, {value: "b"}, {value: "c"}, ]; // 创建计数器对象,用于记录每个value的当前计数 const counter = {}; // 遍历数组生成带groupid的新数组 const result = dataset.map(item => { // 若当前value未被记录,初始计数为0,否则取已有计数,然后+1 counter[item.value] = (counter[item.value] || 0) + 1; // 返回新对象,保留原属性并添加groupid return { ...item, groupid: counter[item.value] }; }); console.log(result); // 输出结果就是你期望的: // [ {value: "a", groupid: 1}, {value: "a", groupid: 2}, {value: "a", groupid: 3}, {value: "b", groupid: 1}, {value: "b", groupid: 2}, {value: "c", groupid: 1}, ]
代码逻辑拆解
counter对象:用来存储每个value对应的当前序号,比如counter["a"]会随着遍历逐步变成1、2、3map方法:遍历原数组的每个元素,返回包含groupid的新对象,不会修改原数组(如果需要修改原数组,可以把map换成forEach,然后直接给item添加groupid属性)- 扩展运算符
...item:确保保留原对象的所有属性(如果以后dataset里的对象有其他字段,也不会丢失)
另一种实现方式(用reduce)
如果你习惯用reduce来处理这类聚合逻辑,也可以这样写:
const result = dataset.reduce((acc, item) => { // 计算当前分组的序号 const currentGroupId = (acc.counter[item.value] || 0) + 1; // 更新计数器 acc.counter[item.value] = currentGroupId; // 把新对象加入结果数组 acc.result.push({ ...item, groupid: currentGroupId }); return acc; }, { counter: {}, result: [] }).result; // 最后取出结果数组部分
这种方式通过reduce同时维护计数器和结果数组,逻辑和map版本完全一致,只是写法不同,你可以根据自己的习惯选择~
内容的提问来源于stack exchange,提问作者MayaGans
相关产品推荐
相关产品推荐

