JavaScript Sort 的一个错误用法示例


Posted in Javascript onMarch 20, 2015

前不久同事的代码中出了一个很神奇的问题,大致流程是对一个由对象组成的数组进行排序,其中属性 a 用于排序,属性 b 作为一个优选条件,当 b 等于 1 的时候无论 a 值是什么,都排在开头 。这本是一个很简单的问题,问题就在于他用两次 sort 实现在这次排序,先根据 a 的属性排序,然后再根据 b 的值来排序。问题就出在第二次排序中。

我们想当然的会认为在第一次排序中,数组已经根据 a 的属性由大到小排序,在第二次中我们只要不去动原数组的顺序就行(一般在方法中写成返回0或-1),只考虑单独把 b 等于 1 的元素提到前面去。但是其实这与语言所选用的排序算法有关,javascript (和一起其他语言)内置的 sort 方法采用的是几种排序算法的集合,有时并不能保证相同元素的位置保持一致。

下面是从 stackoverflow 上面找来的一个例子

var arrayToSort = [

  {name: 'a', strength: 1}, {name: 'b', strength: 1}, {name: 'c', strength: 1}, {name: 'd', strength: 1},

  {name: 'e', strength: 1}, {name: 'f', strength: 1}, {name: 'g', strength: 1}, {name: 'h', strength: 1},

  {name: 'i', strength: 1}, {name: 'j', strength: 1}, {name: 'k', strength: 1}, {name: 'l', strength: 1},

  {name: 'm', strength: 1}, {name: 'n', strength: 1}, {name: 'o', strength: 1}, {name: 'p', strength: 1},

  {name: 'q', strength: 1}, {name: 'r', strength: 1}, {name: 's', strength: 1}, {name: 't', strength: 1}

];
arrayToSort.sort(function (a, b) {

  return b.strength - a.strength;

});
arrayToSort.forEach(function (element) {

  console.log(element.name);

});

我们会以为最后元素的值还是从 a 到 t,但实际运行下来的结果却是乱序的,这是因为 sort 的算法并没有保留原数组的顺序,也即 unstable。

那么我们就该尽量避免这种情况发生,就我同事的例子,将两次 sort 的逻辑合并在一次中应该是个可行的办法,如果必须分为多次 sort,那么就把原数组的顺序记录在元素的属性上把。

Javascript 相关文章推荐
js下关于onmouseout、事件冒泡的问题经验小结
Dec 09 Javascript
JavaScript取得键盘按下方向键是哪个的方法
Aug 04 Javascript
如何实现移动端浏览器不显示 pc 端的广告
Oct 15 Javascript
js生成随机数的过程解析
Nov 24 Javascript
JavaScript中三种异步上传文件方式
Mar 06 Javascript
javascript深拷贝和浅拷贝详解
Feb 14 Javascript
js数组方法reduce经典用法代码分享
Jan 07 Javascript
在Node.js中将SVG图像转换为PNG,JPEG,TIFF,WEBP和HEIF格式的方法
Aug 22 Javascript
小程序使用分包的示例代码
Mar 23 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
Apr 07 Javascript
JS 5种遍历对象的方式
Jun 16 Javascript
详解JavaScript 事件流
Sep 02 Javascript
JS实现的数组全排列输出算法
Mar 19 #Javascript
JavaScript在浏览器标题栏上显示当前日期和时间的方法
Mar 19 #Javascript
JavaScript实现在标题栏上显示当前日期的方法
Mar 19 #Javascript
JavaScript显示当前文档最后修改日期的方法
Mar 19 #Javascript
JavaScript将一个数组插入到另一个数组的方法
Mar 19 #Javascript
JS中prototype的用法实例分析
Mar 19 #Javascript
JS获取Table中td值的方法
Mar 19 #Javascript
You might like
删除无限级目录与文件代码共享
2006/07/12 PHP
php生成xml时添加CDATA标签的方法
2014/10/17 PHP
codeigniter中view通过循环显示数组数据的方法
2015/03/20 PHP
Yii核心验证器api详解
2016/11/23 PHP
javascript Array.remove() 数组删除
2009/08/06 Javascript
jquery中ajax学习笔记一
2011/10/16 Javascript
基于mootools插件实现遮罩层新手引导
2012/05/24 Javascript
jQuery.extend()的实现方式详解及实例
2013/06/29 Javascript
window.location.reload 刷新使用分析(去对话框)
2015/11/11 Javascript
vue中用H5实现文件上传的方法实例代码
2017/05/27 Javascript
angular使用bootstrap方法手动启动的实例代码
2017/07/18 Javascript
基于JavaScript实现微信抢红包功能
2017/07/20 Javascript
angularjs http与后台交互的实现示例
2018/12/21 Javascript
微信小程序时间选择插件使用详解
2018/12/28 Javascript
vue配置文件实现代理v2版本的方法
2019/06/21 Javascript
解决vue项目axios每次请求session不一致的问题
2020/10/24 Javascript
[03:37]2016完美“圣”典 风云人物:Mikasa专访
2016/12/07 DOTA
Python验证码识别处理实例
2015/12/28 Python
Django中自定义admin Xadmin的实现代码
2019/08/09 Python
解决Django layui {{}}冲突的问题
2019/08/29 Python
Python笔记之facade模式
2019/11/20 Python
Python 复平面绘图实例
2019/11/21 Python
jupyter notebook 多行输出实例
2020/04/09 Python
python实现图像外边界跟踪操作
2020/07/13 Python
CSS3动画和HTML5新特性详解
2020/08/31 HTML / CSS
技术总监的工作职责
2013/11/13 职场文书
《童年》教学反思
2014/02/18 职场文书
优秀毕业生找工作自荐信
2014/06/23 职场文书
2014年度党员自我评议
2014/09/13 职场文书
技术入股合作协议书
2014/10/07 职场文书
欢迎家长标语
2014/10/08 职场文书
婚宴父亲致辞
2015/07/27 职场文书
解决python存数据库速度太慢的问题
2021/04/23 Python
Log4j.properties配置及其使用
2021/08/02 Java/Android
Apache Hudi的多版本清理服务彻底讲解
2022/03/31 Servers
美国运营商 T-Mobile 以 117.83Mb/s 的速度排第一位
2022/04/21 数码科技