如何在数组对象中先使用map再用reduce?实现价格累加新数组
问题描述
我希望将数组中每个对象的price与之前所有项的price累加,生成新的数组对象。以下是我的原始数据、期望的目标数组,以及我编写的reducer代码,请问如何正确结合map和reduce实现该需求?
原始数据
const data = [ {price: 2, volume: 123}, {price: 3, volume: 123}, {price: 4, volume: 254}, {price: 1, volume: 444}, {price: 5, volume: 555} ];
期望目标数组(注:示例中volume值疑似笔误,核心需求为price累加)
const finaldata = [ {price: 2, volume: 555}, {price: 5, volume: 777}, // 2+3=5 {price: 9, volume: 5000}, // 2+3+4=9 {price: 10, volume: 8000}, // 2+3+4+1=10 {price: 15, volume: 4000} // 2+3+4+1+5=15 ];
我的代码(存在问题)
const test = buy.map((items, index) => items.reduce((prev, curr, currIndex) => { return index >= currIndex ? { volume: (prev?.volume || 0) + curr?.volume } : 0; }, 0) );
解决方案
你的代码存在两个核心问题:
- 误用了
map的遍历对象:map的回调参数items是数组中的单个对象,不是整个数组,对单个对象执行reduce毫无意义。 - 逻辑方向错误:你当前累加的是
volume,但需求是累加price。
最优实现(仅用reduce,时间复杂度O(n))
其实不需要同时用map和reduce,单独用reduce就能高效完成,因为它可以在遍历过程中维护累加状态:
const finalData = data.reduce((result, currentItem) => { // 计算当前累加的price:如果结果数组已有项,就取最后一项的price加上当前项的price,否则直接用当前项的price const accumulatedPrice = result.length ? result[result.length - 1].price + currentItem.price : currentItem.price; // 保留当前项的volume,替换price为累加后的值,推入结果数组 result.push({ price: accumulatedPrice, volume: currentItem.volume }); return result; }, []);
结合map和reduce的实现(时间复杂度O(n²),仅作演示)
如果一定要按你的思路结合两者,可以这样写:
const finalData = data.map((_, currentIndex) => { // 截取数组的前currentIndex+1项,用reduce累加这些项的price const totalPrice = data.slice(0, currentIndex + 1).reduce((sum, item) => sum + item.price, 0); // 组合成新对象,保留当前项的volume return { price: totalPrice, volume: data[currentIndex].volume }; });
这种方式每次map都会重新对前半段数组执行reduce,性能不如第一种方案,所以优先推荐用reduce单独实现。
内容的提问来源于stack exchange,提问作者sepideh bb
相关产品推荐
相关产品推荐

