数组对象按最小排名升序排序,含null的对象置尾时出现NaN问题
排序后仍出现NaN值的原因分析
需求是将数组按对象中的最小排名升序排序,同时将排名为null的对象放到数组末尾,但运行代码后,排序前和排序后的日志中仍出现NaN值,原因如下:
问题代码
async function getLive(){ let response= await fetch('https://tennisapi1.p.rapidapi.com/api/tennis/events/live', options) let json= await response.json() for(let i=0; i<10;i++){ console.log(json.events[i].awayTeam.ranking<json.events[i].homeTeam.ranking?json.events[i].awayTeam.ranking:json.events[i].homeTeam.ranking) } json.events.sort((a, b) => { let x=1000000 let r1 = Math.min(a.awayTeam.ranking , a.homeTeam.ranking) if(r1===null){ r1=x } x+=1 let r2 = b.awayTeam.ranking < b.homeTeam.ranking ? b.awayTeam.ranking : b.homeTeam.ranking; if(r2===null){ r2=x } x++ return r1 - r2; }); live=json.events console.log('-----------------------------') for(let i=0; i<10;i++){ console.log(Math.min(live[i].awayTeam.ranking ,live[i].homeTeam.ranking)) } }
日志输出
121 NaN NaN 73 192 295 360 394 473 475
原因剖析
Math.min()处理无效值返回NaN
当球队的ranking是null或undefined时,Math.min()会返回NaN:
- 若其中一支球队排名为
null,另一支为有效数字,Math.min(null, 121)会返回NaN; - 若两支球队排名都是
null/undefined,Math.min()同样返回NaN。
而代码仅判断了r1===null的情况,完全没处理r1为NaN的场景,导致这些无效值保留下来,排序时NaN参与运算的结果仍是NaN,排序逻辑直接失效,这些元素无法被放到数组末尾,打印时自然出现NaN。
- 变量
x的逻辑完全无效
排序回调里每次重新初始化x=1000000再递增,但sort的回调函数会被多次调用,每次调用时x都是全新的局部变量,不同null元素被赋予的x值毫无关联,既无法保证所有无排名元素都排在最后,还可能导致无排名元素之间的顺序混乱。
修正方案
使用空值合并运算符??将null/undefined的排名转为Infinity(JS中最大的数值),确保Math.min()不会返回NaN,同时所有无排名元素会被自然排到数组末尾:
async function getLive(){ let response = await fetch('https://tennisapi1.p.rapidapi.com/api/tennis/events/live', options); let json = await response.json(); // 排序前打印,替换NaN为友好提示 for(let i=0; i<10; i++){ const awayRank = json.events[i].awayTeam.ranking ?? Infinity; const homeRank = json.events[i].homeTeam.ranking ?? Infinity; const minRank = Math.min(awayRank, homeRank); console.log(minRank === Infinity ? '无排名' : minRank); } json.events.sort((a, b) => { // 处理a的最小排名,无效值转Infinity const r1 = Math.min( a.awayTeam.ranking ?? Infinity, a.homeTeam.ranking ?? Infinity ); // 处理b的最小排名 const r2 = Math.min( b.awayTeam.ranking ?? Infinity, b.homeTeam.ranking ?? Infinity ); return r1 - r2; }); live = json.events; console.log('-----------------------------'); // 排序后打印,替换NaN为友好提示 for(let i=0; i<10; i++){ const awayRank = live[i].awayTeam.ranking ?? Infinity; const homeRank = live[i].homeTeam.ranking ?? Infinity; const minRank = Math.min(awayRank, homeRank); console.log(minRank === Infinity ? '无排名' : minRank); } }
内容的提问来源于stack exchange,提问作者w4ss
相关产品推荐
相关产品推荐

