Chrome谷歌浏览器中js代码Array.sort排序的bug乱序解决办法
【现象】
代码如下:
var list = [{ n: "a", v: 1 }, { n: "b", v: 1 }, { n: "c", v: 1 }, { n: "d", v: 1 }, { n: "e", v: 1 }, { n: "f", v: 1 }, { n: "g", v: 1 }, { n: "h", v: 1 }, { n: "i", v: 1 }, { n: "j", v: 1 }, { n: "k", v: 1 }, ];
list.sort(function (a, b) {
return a.v - b.v;
});
for (var i = 0; i < list.length; i++) {
console.log(list[i].n);
}
很简单,就是定一个对象数组,再用sort方法按v字段对其排序,这个问题很容易让人忽略,因为按正常思维都会认为只要所有v是相等的那么结果就跟没排序之前是一样的,但是……
结果如下:
====IE11====

====火狐====

====Chrome====

可以看出,IE跟火狐都没问题,但Chrome却成了乱序。
经过查阅资料,网上对这个问题似乎没有多少实际的解决办法。据说谷歌开发者认为这不是个bug不予解决,因为V8引擎的原因,为了高效排序,称之为不稳定排序。其实这也不算是一个BUG,不同人会有不同的看法:a:"因为排序依据是相同的就是没有顺序,没有顺序就是乱序,这种结果是正确的";b:"既然排序依据是相同的那就按照原始顺序输出"(这应该是大多数据语言里常规的做法)。网上有牛人说数组超过10条后会调用另一种排序方法(插入排序),10以下用的是快速排序算法,为了提交效率,所以会出现这种情况。
网上有人给出了办法就是相同的情况下强制产生差异(当顺序相同时,让a比b小):
list.sort(function (a, b) {
return a.v - b.v || -1;
});
经测试,该方法无效。原因可能是返回值都相同导致。
很苦恼,于是继续想办法,既然返回值相同也会出现这个问题,那如何能让返回值即不相同排序结果还要正确呢?于是经过一番思索,想到了一个值:index,没错!就是根据索引来排序,如果顺序相同那么就根据比较索引,索引的顺序就是排序前的顺序,于是代码改为:
list.sort(function (a, b) {
return a.v - b.v || list.indexOf(a)-list.indexOf(b);
});
测试结果仍然不行。
有些苦恼,仔细想了一下发现:思路是没有问题,但是在排序中元素位置是不断发生变化的,所以indexOf取出的不是原始的索引位置,所以排序仍然不正确。因此按照这个思路去做,在每个元素里加个属性来保留它原始的索引,然后再按此索引排序,代码更改后如下:
for (var i = 0; i < list.length; i++) {
list[i].oldIndex = i;
}
list.sort(function (a, b) {
return a.v - b.v || a.oldIndex - b.oldIndex;
});
测试结果没问题,跟我们预期的相同!
【解决办法】
于是正确结果就是:先循环给每个元素增加一个属性,用来保存它目前的位置,然后再排序中遇到等序时取索引进行排序
例如:
for (var i = 0; i < list.length; i++) {
list[i].oldIndex = i;
}
list.sort(function (a, b) {
return a.v - b.v || a.oldIndex - b.oldIndex;
});
Chrome谷歌浏览器中js代码Array.sort排序的bug乱序解决办法的更多相关文章
- Win7无法将图标(Chrome谷歌浏览器更新后无法锁定也适用)锁定到任务栏解决办法
“将程序锁定到任务栏”是Windows 7中的一个非常有用的功能,它比之前的快速启动栏要来得简洁.但是我用了一段时间之后,发现“锁定到任务栏”这一个选项消失了,对图标点右键找不到这个图标,直接把图标拖 ...
- C#调用存储过程中事务级临时表返回DataTable列乱序解决办法
string result = strSqlResult.Substring(3).Trim().Replace("\n", "").Replace(" ...
- chrome如何禁用js代码
chrome如何禁用js代码 一.总结 一句话总结: 设置-->高级-->隐私设置和安全性-->网站设置-->javascript 中禁止javascript即可 二.chro ...
- 总结下js排序算法和乱序算法
其实本人最怕的就是算法,大学算法课就感觉老师在讲天书,而且对于前端来说,算法在实际的应用中实在是很有限.毕竟算法要依靠大量的数据为基础才能发挥出算法的效率,就浏览器那性能,......是吧,退一万步说 ...
- Python中,os.listdir遍历纯数字文件乱序如何解决
Python中,os.listdir遍历纯数字文件乱序如何解决 日常跑深度学习视觉相关代码时,常常需要对数据集进行处理.许多图像文件名是利用纯数字递增的方式命名.通常所用的排序函数sort(),是按照 ...
- 【转】Android Fragment中使用SurfaceView切换时闪一下黑屏的解决办法
重构了下之前自己的一个新闻客户端,全部使用了Fragment来进行页面切换,只有一个入口Activity作为程序的启动Activity,其中有一个界面需要调用摄像头识别二维码, 于是就会用到Surfa ...
- 【转】Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解决办法)
原文网址:http://www.blogjava.net/anchor110/articles/355699.html 1.在工程下新建lib文件夹,将需要的第三方包拷贝进来.2.将引用的第三方包,添 ...
- HTML中的select下拉框内容显示不全的解决办法
HTML中的select下拉框内容显示不全的解决办法 今天,我遇到这样一个问题:查询栏中的下拉框中的内容过长,导致部分被覆盖了. 查询了一些资料,有的说用函数控制,有的说用事件控制,有的看不懂,有的实 ...
- 代码漏洞扫描描述Cross Site History Manipulation解决办法[dongcoder.com]
代码漏洞扫描 漏洞描述:Cross Site History Manipulation 简要描述:产品的行为差异或发送不同的反应,在某种程度上暴露了与安全性相关的产品状态,例如特定的操作是否成功.可能 ...
随机推荐
- completer自动完成
由于项目需要,在输入框中要做一些输入限制的同时,更加要求用户体验,提供一些自动完成设置.所以有需求,总会有解决方式,下面说一下自动完成插件的原理: html的body部分: <span styl ...
- Javascript之入门篇(一)
上一篇学习了什么是JavaScript语言及其作用和特有的特点等,本篇将详细介绍JavaScript一些入门使用方式. 对于初学者来讲,由于JavaScript是嵌入到HTML页面里面的,首先创建一张 ...
- web.xml 有什么用?(Java框架)
1.每个javaEE工程中都有web.xml文件,那么它的作用是什么呢?它是每个web.xml工程都必须的吗? 一个web中可以没有web.xml文件,也就是说,web.xml文件并不是web工程 ...
- ipad中icon与launchimage的size
图标(AppIcon)与启动图(LaunchImage)是开发iOS应用程序必不可少的内容,但是在网络上对于这部分的内容讲解的并不详细,所以花些时间写了这篇文章,希望有需要的朋友可以随时查看 想知道A ...
- p2p-如何拯救k8s镜像分发的阿喀琉斯之踵?
K8s的出现为PaaS行业的发展打了一针兴奋剂,Docker+k8s的技术路线已经成为了容器云的主流.尤其针对大流量,大弹性的应用场景来说,k8s将其从繁杂的运维.部署工作中彻底拯救出来.然而事情往往 ...
- ArcGIS api for javascript-图层控制(图层树)
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 添加fping监控
第一步:安装fping服务 yum -y install fping 第二步:在zabbix-server服务端上启用fping服务 重启zabbix-server 第三步:在主机上添加fping监控 ...
- 利用zookeeper生成唯一id,通用性代码
在上篇中是写死的,这章就写出通用的 package com.cxy.com.cxy.curator; import java.util.concurrent.ExecutorService; impo ...
- Mybatis学习笔记(三) —— DAO开发方法
一.SqlSession的使用范围 SqlSession中封装了对数据库的操作,如:查询.插入.更新.删除等. SqlSession通过SqlSessionFactory创建. SqlSessionF ...
- php内置web server
今天刚开始正式学习PHP(之前有一点了解),推荐学习的网站是w3school.一开始不知道tomcat服务器不支持PHP脚本,直接把.php文件放到tomcat里面去运行,结果嵌入的php代码段没有什 ...