JavaScript实现循环数组key个相邻元素求和生成新数组技术问询
拆弹序列实现的正确性验证与优化方案
首先,咱们先看你给出的这段实现代码——对于题目里key为正数的场景,它是完全正确的!拿你提供的示例输入message=[4,2,-5,11]、size=4、key=3来测试,这段代码确实能输出预期的[8,10,17,1],逻辑没问题:外层循环遍历每个元素,内层循环累加当前元素后续key个位置的元素值,利用(i+j)%size实现了数组的循环结构,这个思路很准确。
不过这段代码还有几个可以改进的地方,以及一个功能缺失:
现存问题&优化方向
1. 未处理key为负数的场景
题目里明确说明key可以是负数,此时需要替换为当前元素前|key|个数字的和。原代码只处理了key为正的情况,遇到负key就会出错。
2. 变量声明存在全局污染风险
代码里的sum、newArr都用var声明(甚至sum没声明直接用),在非严格模式下会成为全局变量,容易引发意外问题,建议用let/const来声明块级作用域变量。
3. 代码可复用性差
当前代码是硬编码的测试值,没有封装成题目要求的函数形式,无法直接复用处理不同的输入。
优化后的完整实现
下面是封装成函数、支持正负key、避免全局污染的版本:
function defuseBomb(size, key, message) { // 处理key为0的特殊情况(题目未明确说明,若key=0可返回全0数组或按需调整) if (key === 0) { return Array(size).fill(0); } return message.map((_, index) => { let sum = 0; const absKey = Math.abs(key); for (let j = 1; j <= absKey; j++) { // 根据key正负计算目标索引,加size再取模避免负数索引 const targetIndex = key > 0 ? (index + j) % size : (index - j + size) % size; sum += message[targetIndex]; } return sum; }); } // 测试示例 const testMessage = [4, 2, -5, 11]; console.log(defuseBomb(4, 3, testMessage)); // 输出 [8, 10, 17, 1] // 测试负key场景:key=-2,每个元素是前2个元素的和 console.log(defuseBomb(4, -2, testMessage)); // 输出 [-4, 15, 6, -3]
额外简洁化优化思路
如果想让代码更函数式,可以用Array.from结合reduce替代内层for循环,代码更紧凑:
function defuseBomb(size, key, message) { if (key === 0) return Array(size).fill(0); const absKey = Math.abs(key); return message.map((_, i) => { return Array.from({ length: absKey }, (_, j) => { const idx = key > 0 ? (i + j + 1) % size : (i - j - 1 + size) % size; return message[idx]; }).reduce((acc, curr) => acc + curr, 0); }); }
这个版本用Array.from生成指定长度的数组,映射每个需要累加的元素后用reduce求和,可读性因人而异,按需选择即可。
内容的提问来源于stack exchange,提问作者user5711656
相关产品推荐
相关产品推荐

