JavaScript中合并含重复值的两数组为键值对对象的方法
问题:将两个数组映射为键值对对象(重复键对应值存入数组)
给定两个长度相等、可能包含重复值的数组A和B,需要将它们映射为键值对对象:当数组A中的键重复时,将数组B对应位置的值推入该键对应的数组中。示例如下:
A = [2,3,1,3,2,0] B = [1,4,5,6,3,2] // 期望得到的对象 obj = {'2': [1,3], '3': [4,6], '1': [5], '0': [2]}
我尝试用reduce方法实现,但结果不符合预期,代码如下:
A = [2,3,1,3,2,0]; B = [1,4,5,6,3,2]; var result = A.reduce(function (obj, id, index) { obj[id] = obj[id] ? obj[id].push(B[index]) : (obj[id] = [B[index]]); return obj; }, {}); console.log('result', result);
问题原因
你的代码核心问题在于Array.push()的返回值:push方法执行后返回的是数组新的长度(数字类型),而非数组本身。
当数组A中第一次出现某个键时,你会给obj[id]赋值为包含对应B值的数组;但第二次遇到相同键时,你执行obj[id].push(B[index]),此时obj[id]会被赋值成这个push操作返回的数组长度(比如第一次push后长度是2,就会把obj[id]改成2)。后续再遇到相同键时,就会尝试对数字调用push方法,直接报错,最终结果自然不符合预期。
修正后的代码
这里提供几种可行的修正方案:
方案一:先初始化再push(最直观)
A = [2,3,1,3,2,0]; B = [1,4,5,6,3,2]; var result = A.reduce(function (obj, id, index) { // 若键不存在,先初始化空数组 if (!obj[id]) { obj[id] = []; } // 向数组中添加对应值 obj[id].push(B[index]); return obj; }, {}); console.log('result', result); // 输出:{ '0': [2], '1': [5], '2': [1,3], '3': [4,6] }
方案二:用逻辑或简化初始化
A = [2,3,1,3,2,0]; B = [1,4,5,6,3,2]; var result = A.reduce(function (obj, id, index) { // 逻辑或:若obj[id]不存在则初始化为空数组 obj[id] = obj[id] || []; obj[id].push(B[index]); return obj; }, {}); console.log('result', result);
方案三:ES6+展开语法(无修改原数组)
如果你的环境支持ES6及以上,可以用更简洁的写法,这种方式不会修改原数组,但数据量大时性能略逊于前两种:
const A = [2,3,1,3,2,0]; const B = [1,4,5,6,3,2]; const result = A.reduce((obj, id, index) => { obj[id] = [...(obj[id] || []), B[index]]; return obj; }, {}); console.log('result', result);
内容的提问来源于stack exchange,提问作者Exodus Reed
相关产品推荐
相关产品推荐

