使用Array.reduce()后为何出现undefined元素?
问题:reduce处理后的数组末尾出现undefined元素
我正在学习JavaScript,目前在进行数组、JSON对象以及sort和reduce方法的实验,目标是找到Codility的NumberOfDiscIntersections任务的优质解决方案。参考过现有方案后尝试自行复现,代码接近完成,但执行后发现reduce处理后的数组输出末尾出现了一个'undefined'元素。
我的JavaScript代码
C = [2, 1, 1, 3, 2, 3]; answer = solution(C); console.log(answer); //circle radius varies from 0..2147483647 function solution(A) { //marker = {spot:0, openers:0, closers:0}; const N = A.length; const points = []; let left = 0; let right = 0; // First, I count all borders for (i = 0; i < N; i++) { left = i - A[i]; right = i + A[i]; points.push({ "position": left, "openers": 1, "closers": 0 }); points.push({ "position": right, "openers": 0, "closers": 1 }); } console.log("points before sort:") for (item of points) { console.log(item); } points.sort((a, b) => { if (a.position < b.position) { return -1; } else if (a.position > b.position) { return 1; } return 0; }); console.log("points after sort:") for (item of points) { console.log(item); } let parseable = points.reduce((acc, object) => { var index = acc.map((o) => o.position).indexOf(object.position); if (index == -1) { acc.push(object); } else { acc[index].openers += object.openers; acc[index].closers += object.closers; } return acc; }, []); console.log("points after reduce:") for (item of parseable) { console.log(item); } }
控制台输出
points before sort: position: -2, openers: 1, closers: 0 } position: 2, openers: 0, closers: 1 } position: 0, openers: 1, closers: 0 } position: 2, openers: 0, closers: 1 } position: 1, openers: 1, closers: 0 } position: 3, openers: 0, closers: 1 } position: 0, openers: 1, closers: 0 } position: 6, openers: 0, closers: 1 } position: 2, openers: 1, closers: 0 } position: 6, openers: 0, closers: 1 } position: 2, openers: 1, closers: 0 } position: 8, openers: 0, closers: 1 } points after sort: position: -2, openers: 1, closers: 0 } position: 0, openers: 1, closers: 0 } position: 0, openers: 1, closers: 0 } position: 1, openers: 1, closers: 0 } position: 2, openers: 0, closers: 1 } position: 2, openers: 0, closers: 1 } position: 2, openers: 1, closers: 0 } position: 2, openers: 1, closers: 0 } position: 3, openers: 0, closers: 1 } position: 6, openers: 0, closers: 1 } position: 6, openers: 0, closers: 1 } position: 8, openers: 0, closers: 1 } points after reduce: position: -2, openers: 1, closers: 0 } position: 0, openers: 2, closers: 0 } position: 1, openers: 1, closers: 0 } position: 2, openers: 2, closers: 2 } position: 3, openers: 0, closers: 1 } position: 6, openers: 0, closers: 2 } position: 8, openers: 0, closers: 1 } undefined
原因分析与解决方法
这个undefined不是reduce处理后的parseable数组里的元素,而是来自你开头的console.log(answer);——因为你的solution函数没有定义返回值,JavaScript中函数默认返回undefined,所以answer变量的值就是undefined,最后打印它就输出了这个结果。你循环打印parseable的7个元素都是正常的,之后的undefined是单独的console.log(answer)输出。
解决方法
在solution函数末尾加上返回语句,把处理后的数组返回:
// 在函数最后添加这一行 return parseable;
这样answer就会拿到parseable数组的值,console.log(answer)就会输出正确的数组内容,不会再出现undefined。
额外优化提示
另外,针对Codility的NumberOfDiscIntersections任务,你的sort逻辑需要调整:当两个点的position相同时,应该优先处理openers(先加打开的圆盘)再处理closers(再减关闭的圆盘),否则会漏算相交的情况。可以修改sort函数:
points.sort((a, b) => { if (a.position !== b.position) { return a.position - b.position; } // 位置相同时,openers在前(因为打开操作要先执行) return b.openers - a.openers; });
内容的提问来源于stack exchange,提问作者Andre Soeiro
相关产品推荐
相关产品推荐

