嵌套数组值求和:reduce嵌套写法是否高效?有无更优方案?
嵌套数组值求和的更优方案
你当前用嵌套reduce计算水果total总和的写法是可行的,但存在缺少初始值的潜在问题——如果某个item的fruits为空数组,内层reduce会返回undefined,最终导致求和结果变成NaN;如果items本身为空,外层reduce还会直接报错。另外,从可读性和性能角度,还有几种更优的实现方式:
1. 扁平化数组后求和(可读性优先)
先用flatMap把所有水果对象合并成一个一维数组,再用reduce求和,代码结构更直观:
const sumOfFruits = items .flatMap(item => item.fruits) .reduce((sum, fruit) => sum + fruit.total, 0);
如果运行环境不支持flatMap,可以用concat配合展开运算符实现扁平化:
const sumOfFruits = [].concat(...items.map(item => item.fruits)) .reduce((sum, fruit) => sum + fruit.total, 0);
2. 双层循环累加(性能优先)
直接用for...of双层循环手动累加,避免了reduce的函数调用开销,在大数据量场景下性能最优:
let sumOfFruits = 0; for (const item of items) { for (const fruit of item.fruits) { sumOfFruits += fruit.total; } }
也可以用传统的for循环,性能和for...of接近:
let sumOfFruits = 0; for (let i = 0; i < items.length; i++) { const fruits = items[i].fruits; for (let j = 0; j < fruits.length; j++) { sumOfFruits += fruits[j].total; } }
3. 优化后的嵌套reduce(健壮性修复)
如果坚持使用嵌套reduce,一定要加上初始值,保证空数组场景下的正确性:
const sumOfFruits = items.reduce((sum, curr) => { return sum + curr.fruits.reduce((fruitSum, fruitCurr) => fruitSum + fruitCurr.total, 0); }, 0);
性能对比
- 小数据量场景:几种方法性能差异可以忽略,优先选择可读性高的方案(比如
flatMap+reduce)。 - 大数据量场景:双层循环的性能最优,嵌套
reduce和flatMap+reduce性能相近,差异主要来自函数调用的额外开销。
内容的提问来源于stack exchange,提问作者cafe123
相关产品推荐
相关产品推荐

