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的插件教程(Plugin)
Sep 03 Javascript
js保留两位小数使用toFixed实现
Jul 29 Javascript
window.location.reload 刷新使用分析(去对话框)
Nov 11 Javascript
Node.js+Express配置入门教程详解
May 19 Javascript
基于bootstrop常用类总结(推荐)
Sep 11 Javascript
基于jquery实现五星好评
Nov 18 jQuery
Vue.JS项目中5个经典Vuex插件
Nov 28 Javascript
简易Vue评论框架的实现(父组件的实现)
Jan 08 Javascript
JavaScript中使用import 和require打包后实现原理分析
Mar 07 Javascript
vue cli 3.0 搭建项目的图文教程
May 17 Javascript
vue 获取视频时长的实例代码
Aug 20 Javascript
uni app仿微信顶部导航条功能
Sep 17 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下用rmdir实现删除目录的三种方法小结
2008/04/20 PHP
PHP取整数函数常用的四种方法小结
2012/07/05 PHP
php模拟ping命令(php exec函数的使用方法)
2013/10/25 PHP
ThinkPHP访问不存在的模块跳转到404页面的方法
2014/06/19 PHP
laravel 数据迁移与 Eloquent ORM的实现方法
2019/04/12 PHP
PHP二维索引数组的遍历实例分析【2种方式】
2019/06/24 PHP
关于跨站脚本攻击问题
2011/12/22 Javascript
javascript中如何处理引号编码"
2013/08/15 Javascript
js加载读取内容及显示与隐藏div示例
2014/02/13 Javascript
JsRender实用入门教程
2014/10/31 Javascript
jQuery中prevAll()方法用法实例
2015/01/08 Javascript
Javascript模仿淘宝信用评价实例(附源码)
2015/11/26 Javascript
js中最容易被忽视的事件问题大总结
2016/05/15 Javascript
D3.js实现散点图和气泡图的方法详解
2016/09/21 Javascript
jquery插件bootstrapValidator表单验证详解
2016/12/15 Javascript
详解JS获取HTML DOM元素的8种方法
2017/06/17 Javascript
JS实现简单短信验证码界面
2017/08/07 Javascript
vue基于Element构建自定义树的示例代码
2017/09/19 Javascript
浅谈Three.js截图并下载的大坑
2019/11/01 Javascript
Bootstrap table 服务器端分页功能实现方法示例
2020/06/01 Javascript
python中from module import * 的一个坑
2014/07/20 Python
python标准算法实现数组全排列的方法
2015/03/17 Python
Python 'takes exactly 1 argument (2 given)' Python error
2016/12/13 Python
在Python中实现替换字符串中的子串的示例
2018/10/31 Python
详解分布式任务队列Celery使用说明
2018/11/29 Python
使用Python制作简单的小程序IP查看器功能
2019/04/16 Python
keras 模型参数,模型保存,中间结果输出操作
2020/07/06 Python
Python爬虫之Selenium实现键盘事件
2020/12/04 Python
html5 sessionStorage会话存储_动力节点Java学院整理
2017/07/06 HTML / CSS
韩国著名的在线综合购物网站:Akmall
2016/08/07 全球购物
澳大利亚便宜隐形眼镜购买网站:QUICKLENS Australia
2018/10/06 全球购物
建筑工程专业学生的自我评价
2013/12/25 职场文书
工程技术员岗位职责
2014/03/02 职场文书
初中重阳节活动总结
2015/05/05 职场文书
幼儿园教学工作总结2015
2015/05/12 职场文书
如何用JavaScript学习算法复杂度
2021/04/30 Javascript