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 相关文章推荐
javascript之bind使用介绍
Oct 09 Javascript
JS声明变量背后的编译原理剖析
Dec 28 Javascript
jQuery和hwSlider实现内容响应式可触控滑动切换效果附源码下载(二)
Jun 22 Javascript
ajax 提交数据到后台jsp页面及页面跳转问题
Jan 19 Javascript
Vue.js实战之组件的进阶
Apr 04 Javascript
javascript实现动态显示颜色块的报表效果
Apr 10 Javascript
微信小程序仿美团城市选择
Jun 06 Javascript
微信小程序 select 下拉框组件功能
Sep 09 Javascript
解决layui数据表格排序图标被超出的表头挤出去的问题
Sep 19 Javascript
countup.js实现数字动态叠加效果
Oct 17 Javascript
你知道JavaScript Symbol类型怎么用吗
Jan 08 Javascript
vue中js判断长时间不操作界面自动退出登录(推荐)
Jan 22 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
php array的学习笔记
2012/05/16 PHP
PHP读取Excel类文件
2017/05/15 PHP
PHP PDOStatement::bindColumn讲解
2019/01/30 PHP
PHP实现简单登录界面
2019/10/23 PHP
解决AJAX中跨域访问出现'没有权限'的错误
2008/08/20 Javascript
js replace正则表达式应用案例讲解
2013/01/17 Javascript
JavaScript中setInterval的用法总结
2013/11/20 Javascript
JavaScript获取table中某一列的值的方法
2014/05/06 Javascript
js实现图片在未加载完成前显示加载中字样
2014/09/03 Javascript
从JQuery源码分析JavaScript函数的apply方法与call方法
2014/09/25 Javascript
JS实现文件动态顺序载入的方法
2015/03/07 Javascript
jquery实现的代替传统checkbox样式插件
2015/06/19 Javascript
javascript日期验证之输入日期大于等于当前日期
2015/12/13 Javascript
jQuery 生成svg矢量二维码
2016/08/09 Javascript
Vue.extend构造器的详解
2017/07/17 Javascript
在小程序开发中使用npm的方法
2018/10/17 Javascript
vue中实现图片压缩 file文件的方法
2020/05/28 Javascript
Python3指定路径寻找符合匹配模式文件
2015/05/22 Python
解决python os.mkdir创建目录失败的问题
2018/10/16 Python
Django实现跨域请求过程详解
2019/07/25 Python
如何在Django项目中引入静态文件
2019/07/26 Python
Pytorch 的损失函数Loss function使用详解
2020/01/02 Python
flask框架蓝图和子域名配置详解
2020/01/25 Python
Python函数参数定义及传递方式解析
2020/06/10 Python
canvas实现圆绘制的示例代码
2019/09/11 HTML / CSS
浅析HTML5中header标签的用法
2016/06/24 HTML / CSS
萌新HTML5 入门指南(二)
2020/11/09 HTML / CSS
PyQt 如何创建自定义QWidget
2021/03/24 Python
中学劳技课教师的自我评价
2014/02/05 职场文书
自我鉴定总结
2014/03/24 职场文书
行政执法作风整顿剖析材料
2014/10/11 职场文书
同步小康驻村工作简报
2015/07/20 职场文书
MySQL 四种连接和多表查询详解
2021/07/16 MySQL
Spring Boot DevTools 全局配置学习指南
2022/03/31 Java/Android
mysql实现将字符串字段转为数字排序或比大小
2022/06/14 MySQL
JavaScript实现一键复制内容剪贴板
2022/07/23 Javascript