JS对比两个数组 计算最后变更元素及其之前所有元素的和
需求说明
- 对比两个数组的差异,返回发生变更的元素之前(包含该变更元素自身)的所有数组元素之和。
- 维护两组区域高度数组,输入值变化时自动更新:如果数组中有2个及以上元素发生变更,累加所有变更元素,以及最后一个变更元素之前的所有元素总和。
- 基础示例:
let oldArea = [3, 4, 2] let newArea = [3, 6, 2]
原有实现通过硬编码数组下标做判断,仅能适配固定长度的数组,扩展性差,原代码如下:
let oldArea = [3, 4, 2] let newArea = [3, 6, 2] let changedArea = []; if ( oldArea[0] !== newArea[0] && oldArea[1] === newArea[1] ) { changedArea.push(newArea[0]); } else if ( oldArea[1] !== newArea[1] && oldArea[0] === newArea[0] && oldArea[2] === newArea[2] ) { changedArea.push(newArea[0] + newArea[1]); } else changedArea.push(newArea.reduce((a, b) => a + b, 0)); let changedAreaHeight = changedArea.reduce((a, b) => a + b, 0); console.log(changedAreaHeight)
优化实现方案
核心逻辑是先遍历定位到最后一个发生变更的元素下标,再直接对新数组从开头到该下标的所有元素求和,全程不需要硬编码下标,可适配任意长度的数组。
function calcChangedTotal(oldArr, newArr) { const minLength = Math.min(oldArr.length, newArr.length) let lastChangedIndex = -1 // 遍历找出所有值不匹配的位置,记录最后一个匹配失败的下标 for (let i = 0; i < minLength; i++) { if (oldArr[i] !== newArr[i]) { lastChangedIndex = i } } // 兼容两数组长度不一致的边界场景,超出部分视为变更 if (oldArr.length !== newArr.length) { lastChangedIndex = Math.max(oldArr.length, newArr.length) - 1 } // 无任何变更直接返回0 if (lastChangedIndex === -1) return 0 // 累加新数组从开头到最后一个变更位的所有值 return newArr .slice(0, lastChangedIndex + 1) .reduce((sum, current) => sum + current, 0) } // 测试验证 console.log(calcChangedTotal([3,4,2], [3,6,2])) // 输出 9(3+6),和原逻辑结果一致 console.log(calcChangedTotal([3,4,2], [5,4,2])) // 输出 5 console.log(calcChangedTotal([3,4,2], [3,4,7])) // 输出 14(3+4+7) console.log(calcChangedTotal([3,4,2], [5,6,2])) // 输出 11(5+6) console.log(calcChangedTotal([1,2,3,4,5], [1,2,0,4,5])) // 输出 3(1+2+0),可直接适配长度为5及以上的数组
方案优势
- 无硬编码下标逻辑,支持任意长度的输入数组,不需要随着数组长度扩展修改判断条件
- 自动兼容两个数组长度不一致的边界场景
- 单次遍历即可完成定位,时间复杂度O(n),执行效率更高
- 逻辑分层清晰,后续维护成本低
内容的提问来源于stack exchange,提问作者WhiteEyes
相关产品推荐
相关产品推荐

