如何使用Array.prototype.reduce()合并同首元素嵌套数组并修改原数组?
问题
我有一个嵌套数组:
const arrayDaddy = [[x, 1], [x, 1], [y, 2], [y, 2], [y, 2], [z, 3]]
我的目标是修改这个arrayDaddy:将首元素相同的嵌套数组的第二个元素相加,并移除首元素重复的嵌套数组,最终得到:
arrayDaddy = [[x, 2], [y, 6], [z, 3]]
请问能否使用Array.prototype.reduce()实现该需求?若不能,有什么简单可行的方法?
注:所有首元素相同的嵌套数组,其第二个元素的值也完全一致。
我曾尝试使用reduce()但未成功,代码如下:
const arrayDaddy = [[x, 1], [x, 1], [y, 2], [y, 2], [y, 2], [z, 3]] ; arrayDaddy.reduce((arr1, arr2) => { if(arr1[0] === arr2[0]){ arr1[1] += arr2[1] // 此处想删除arr2,但无法对局部变量使用delete? } else { // 无操作,继续处理下一个数组 } });
我也考虑过使用map方法,但希望避免创建新数组,要直接修改arrayDaddy本身。
解答
能不能用reduce()实现?
可以,但你之前的写法逻辑有误:reduce默认用数组第一个元素当累加器,后续迭代只处理剩余元素,而且你试图直接在reduce里删除原数组元素的思路不对——reduce更适合生成统计结构,再结合重置原数组的方式来实现需求。
方法1:用reduce统计后修改原数组
先通过reduce生成一个映射表记录每个首元素的总和,再清空原数组并填充统计结果,本质是直接修改原数组:
const arrayDaddy = [['x', 1], ['x', 1], ['y', 2], ['y', 2], ['y', 2], ['z', 3]]; // 用reduce统计每个首元素的总和 const sumMap = arrayDaddy.reduce((map, [key, val]) => { map.set(key, (map.get(key) || 0) + val); return map; }, new Map()); // 清空原数组并填充结果 arrayDaddy.length = 0; sumMap.forEach((total, key) => arrayDaddy.push([key, total])); console.log(arrayDaddy); // 输出 [['x', 2], ['y', 6], ['z', 3]]
方法2:直接遍历原数组修改(无额外结构)
如果不想用额外的映射,直接反向遍历原数组(避免正向删除元素导致索引错乱),找到重复项就累加值并删除当前项:
const arrayDaddy = [['x', 1], ['x', 1], ['y', 2], ['y', 2], ['y', 2], ['z', 3]]; // 反向遍历,从最后一个元素往前处理 for (let i = arrayDaddy.length - 1; i >= 0; i--) { const current = arrayDaddy[i]; // 往前找相同首元素的项 for (let j = i - 1; j >= 0; j--) { if (arrayDaddy[j][0] === current[0]) { arrayDaddy[j][1] += current[1]; arrayDaddy.splice(i, 1); // 删除当前重复项 break; // 题目说明同首元素的第二个值一致,找到一个就停止 } } } console.log(arrayDaddy); // 输出 [['x', 2], ['y', 6], ['z', 3]]
你的reduce写法失败的原因
你没给reduce指定初始累加器,导致累加器一开始是数组第一个元素[x,1],处理第二个元素[x,1]时累加成功,但处理第三个元素[y,2]时,因为arr1[0]是x不等于y,reduce默认返回arr1(也就是[x,2]),后续所有迭代都不会再处理y、z相关元素,最终reduce返回的是[x,2],但原数组完全没被修改,这就是问题所在。
内容的提问来源于stack exchange,提问作者alex the listener
相关产品推荐
相关产品推荐

