如何用JS的map()或reduce()实现数组元素按条件计算待处理数量
用map()或reduce()实现需求
需求回顾
检查array1中的项是否存在于array2中:
- 若存在(匹配条件:第0位ID和第1位名称均一致),用
array1的第3位(col4)减去array2的第4位(col5)得到待处理数量,若结果大于0则替换array1项的第4位;否则保留原项 - 若不存在,直接保留
array1的原项
优化思路
先将array2转换为键值对映射,把匹配标识(ID+名称)作为键,对应待减的数值作为值,将嵌套循环的O(n²)时间复杂度优化为O(n),再结合map()或reduce()处理array1。
方案1:使用map() + 对象映射
let array1 = [ [1, "Item A", "Food", 10, 0], [2, "Item B", "Food", 5, 0], [3, "Item C", "Food", 30, 0] ]; let array2 = [ [1, "Item A", "Food", 5, 3], [3, "Item C", "Food", 10, 5] ]; // 构建array2的映射表:键为"ID-名称",值为需要减去的col5数值 const array2Map = array2.reduce((map, item) => { const key = `${item[0]}-${item[1]}`; map[key] = item[4]; return map; }, {}); // 用map遍历处理array1的每一项 const result = array1.map(item => { const key = `${item[0]}-${item[1]}`; // 复制原数组,避免修改原数据 const newItem = [...item]; if (array2Map.hasOwnProperty(key)) { const pendingQty = newItem[3] - array2Map[key]; // 仅当结果大于0时更新待处理数量 newItem[4] = pendingQty > 0 ? pendingQty : newItem[4]; } return newItem; }); console.log(result);
输出结果
[ [1, "Item A", "Food", 10, 7], [2, "Item B", "Food", 5, 0], [3, "Item C", "Food", 30, 25] ]
方案2:使用reduce()实现
如果习惯用reduce()构建结果数组,逻辑和上述一致:
let array1 = [ [1, "Item A", "Food", 10, 0], [2, "Item B", "Food", 5, 0], [3, "Item C", "Food", 30, 0] ]; let array2 = [ [1, "Item A", "Food", 5, 3], [3, "Item C", "Food", 10, 5] ]; const array2Map = array2.reduce((map, item) => { const key = `${item[0]}-${item[1]}`; map[key] = item[4]; return map; }, {}); const result = array1.reduce((acc, item) => { const key = `${item[0]}-${item[1]}`; const newItem = [...item]; if (array2Map.hasOwnProperty(key)) { const pendingQty = newItem[3] - array2Map[key]; newItem[4] = pendingQty > 0 ? pendingQty : newItem[4]; } acc.push(newItem); return acc; }, []); console.log(result);
关键说明
- 映射表的作用:避免嵌套循环查找,提升处理效率,尤其当数组规模较大时效果明显
- 数组副本:使用
[...item]创建原数组的浅拷贝,防止修改原array1的内容,保持数据不可变性 - 匹配逻辑:用
ID-名称作为唯一键,和原for循环的匹配条件完全一致
内容的提问来源于stack exchange,提问作者onit
相关产品推荐
相关产品推荐

