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 相关文章推荐
jQuery formValidator表单验证插件开源了 含API帮助、源码、示例
Aug 14 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
Apr 28 Javascript
jQuery多项选项卡的实现思路附样式及代码
Jun 03 Javascript
JavaScript实现Java中StringBuffer的方法
Feb 09 Javascript
浅谈javascript的分号的使用
May 12 Javascript
js简单实现Select互换数据的方法
Aug 17 Javascript
jQuery ready()和onload的加载耗时分析
Sep 08 Javascript
Javascript从数组中随机取出不同元素的两种方法
Sep 22 Javascript
JS新包管理工具yarn和npm的对比与使用入门
Dec 09 Javascript
jQuery animate()实现背景色渐变效果的处理方法【使用jQuery.color.js插件】
Mar 15 Javascript
世界上最短的数字判断js代码
Sep 09 Javascript
jQuery实现鼠标放置名字上显示详细内容气泡提示框效果的方法分析
Apr 04 jQuery
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
PHP - Html Transfer Code
2006/10/09 PHP
PHP调用三种数据库的方法(3)
2006/10/09 PHP
php计算到指定日期还有多少天的方法
2015/04/14 PHP
Laravel使用支付宝进行支付的示例代码
2017/08/16 PHP
thinkPHP5框架接口写法简单示例
2019/08/05 PHP
jquery iframe操作详细解析
2013/11/20 Javascript
JavaScript设计模式之外观模式实例
2014/10/10 Javascript
jQuery验证插件 Validate详解
2014/11/20 Javascript
javascript 判断两个日期之差的示例代码
2015/09/05 Javascript
js过滤HTML标签完整实例
2015/11/26 Javascript
封装属于自己的JS组件
2016/01/27 Javascript
JS中判断null的方法分析
2016/11/21 Javascript
Angular2学习笔记——详解NgModule模块
2016/12/02 Javascript
用原生js做单页应用
2017/01/17 Javascript
react 父组件与子组件之间的值传递的方法
2017/09/14 Javascript
详解node child_process模块学习笔记
2018/01/24 Javascript
详解在vue-cli项目下简单使用mockjs模拟数据
2018/10/19 Javascript
小结Python用fork来创建子进程注意事项
2014/07/03 Python
pandas 数据实现行间计算的方法
2018/06/08 Python
Python实现获取邮箱内容并解析的方法示例
2018/06/16 Python
Python代码打开本地.mp4格式文件的方法
2019/01/03 Python
对python列表里的字典元素去重方法详解
2019/01/21 Python
python绘制多个子图的实例
2019/07/07 Python
Python自动化完成tb喵币任务的操作方法
2019/10/30 Python
免费获得微软MCSD证书赶快行动吧!
2012/11/13 HTML / CSS
HTML5 的新的表单元素(datalist/keygen/output)使用介绍
2013/07/19 HTML / CSS
萨克斯第五大道英国:Saks Fifth Avenue英国
2019/04/01 全球购物
如何估计一张表的大小(假设该表中有1万条数据)
2016/03/27 面试题
计算机网络专业推荐信
2013/11/24 职场文书
社区反邪教工作方案
2014/06/16 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
2014年房产销售工作总结
2014/12/08 职场文书
青年志愿者活动感想
2015/08/07 职场文书
演讲稿之我的初心我的成长
2019/08/12 职场文书
详细聊聊vue中组件的props属性
2021/11/02 Vue.js
oracle设置密码复杂度及设置超时退出的功能
2022/06/28 Oracle