问题

最近在项目中遇到排序没有生效的问题,排查之后发现了是 sort 方法遇到字段 undefined 时需要特殊处理。

数据

  1. var array = [
  2. { number: 2 },
  3. {},
  4. { number: 1 }
  5. ];

使用 sort 方法根据 number 字段从小到大排序

  1. array.sort((a, b) => a.number - b.number);

输出的结果不是我们想要的

  1. [ { number: 2 }, {}, { number: 1 } ]

解决方法

sort 方法提供的排序方法中,如果返回的数字是 0 那么会保持原顺序,如果返回的数字 >0 那么会将 a 至于 b 之后,如果返回的数字 < 0 那么会将 a 至于 b 之前。

如果遇到字段可能是 undefined,那么我们需要特殊判断处理下。

首先判断如果 a,b 的排序字段都是 undefined 返回 0 保持原顺序。

再判断如果 a 的字段是 undefined 但 b 的排序字段存在则返回 >0 将 a 至于 b 之后。

再判断 b 的排序字段如果是 undefined 但 a 的排序字段存在则返回 <0 将 a 至于 b 之前。

最后 a,b 的排序字段都存在时,使用 a,b 的排序字段计算后的返回结果判断顺序

  1. array.sort((a, b) => {
  2. // two undefined values should be treated as equal ( 0 )
  3. if( typeof a.number === 'undefined' && typeof b.number === 'undefined' )
  4. return 0;
  5. // if a is undefined and b isn't a should have a lower index in the array
  6. else if( typeof a.number === 'undefined' )
  7. return 1;
  8. // if b is undefined and a isn't a should have a higher index in the array
  9. else if( typeof b.number === 'undefined' )
  10. return -1;
  11. // if both numbers are defined compare as normal
  12. else
  13. return a.number - b.number;
  14. });

输出结果

  1. [ { number: 1 }, { number: 2 }, {} ]

参考链接