如何将数组元素按正则拆分后,合并相同key的value并求和?
解决数组按key分组求和value的问题
看起来你是想把数组里的字符串按#拆分,将相同key的value求和,最终转换成指定的对象数组。你的现有代码有几个问题导致无法得到预期结果,我来帮你梳理并解决:
你的代码存在的问题
- 重复引用同一个对象:你创建了一个
itemObject,每次循环都修改它的属性然后push到数组里,但所有push的都是同一个对象的引用,最后数组里的所有元素都会是最后一次修改后的结果。 - 缺少分组求和逻辑:你的代码只是把每个元素拆分后直接存入数组,没有判断key是否已经存在,也没有对value进行累加。
- 正则使用问题:全局正则
(/(\d+)#(\d+)/g)配合exec()时,正则的lastIndex会保留上次匹配的位置,可能导致后续匹配异常;其实对于单个字符串的拆分,用非全局正则或者直接split('#')会更简单。
正确的解决方案
我们可以先用一个临时对象来存储每个key的累计值,遍历数组时拆分每个元素的key和value,将value转成数字后累加,最后再把这个对象转换成目标数组格式。
方法一:使用split拆分字符串(简单直观)
let array = ["1#2","2#2","32#1","43#3","44#4","1#1","54#2","1#1"]; // 临时对象存储每个key的求和结果 const sumMap = {}; array.forEach(item => { // 拆分key和value字符串 const [keyStr, valueStr] = item.split('#'); // 转换为数字类型 const key = parseInt(keyStr, 10); const value = parseInt(valueStr, 10); // 累加value:如果key已存在则相加,否则初始化为当前value sumMap[key] = (sumMap[key] || 0) + value; }); // 将对象转换为目标数组格式 const answer = Object.entries(sumMap).map(([key, value]) => ({ key: parseInt(key, 10), value: value })); console.log(answer); // 输出结果:[{ key: 1, value: 4 }, { key: 2, value: 2 }, { key: 32, value: 1 }, { key: 43, value: 3 }, { key: 44, value: 4 }, { key: 54, value: 2 }]
方法二:使用正则表达式匹配
如果你坚持使用正则,可以改用非全局正则(避免lastIndex的问题):
let array = ["1#2","2#2","32#1","43#3","44#4","1#1","54#2","1#1"]; // 去掉全局标志g,每个字符串只匹配一次 const regex = /(\d+)#(\d+)/; const sumMap = {}; array.forEach(item => { const matchResult = regex.exec(item); if (matchResult) { const key = parseInt(matchResult[1], 10); const value = parseInt(matchResult[2], 10); sumMap[key] = (sumMap[key] || 0) + value; } }); const answer = Object.entries(sumMap).map(([key, value]) => ({ key: parseInt(key, 10), value: value })); console.log(answer);
代码说明
- 使用
forEach遍历数组:相比map更适合这类“只做累加操作,不需要返回新数组”的场景。 - 临时对象
sumMap:利用对象key的唯一性,快速判断当前key是否已存在,实现高效累加。 Object.entries():将对象转换为[key, value]格式的数组,再通过map转换成你需要的对象数组结构。
这样就能得到你预期的结果啦!
内容的提问来源于stack exchange,提问作者DevFromEarth
相关产品推荐
相关产品推荐

