【现象】

代码如下:

 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乱序解决办法的更多相关文章

  1. Win7无法将图标(Chrome谷歌浏览器更新后无法锁定也适用)锁定到任务栏解决办法

    “将程序锁定到任务栏”是Windows 7中的一个非常有用的功能,它比之前的快速启动栏要来得简洁.但是我用了一段时间之后,发现“锁定到任务栏”这一个选项消失了,对图标点右键找不到这个图标,直接把图标拖 ...

  2. C#调用存储过程中事务级临时表返回DataTable列乱序解决办法

    string result = strSqlResult.Substring(3).Trim().Replace("\n", "").Replace(" ...

  3. chrome如何禁用js代码

    chrome如何禁用js代码 一.总结 一句话总结: 设置-->高级-->隐私设置和安全性-->网站设置-->javascript 中禁止javascript即可 二.chro ...

  4. 总结下js排序算法和乱序算法

    其实本人最怕的就是算法,大学算法课就感觉老师在讲天书,而且对于前端来说,算法在实际的应用中实在是很有限.毕竟算法要依靠大量的数据为基础才能发挥出算法的效率,就浏览器那性能,......是吧,退一万步说 ...

  5. Python中,os.listdir遍历纯数字文件乱序如何解决

    Python中,os.listdir遍历纯数字文件乱序如何解决 日常跑深度学习视觉相关代码时,常常需要对数据集进行处理.许多图像文件名是利用纯数字递增的方式命名.通常所用的排序函数sort(),是按照 ...

  6. 【转】Android Fragment中使用SurfaceView切换时闪一下黑屏的解决办法

    重构了下之前自己的一个新闻客户端,全部使用了Fragment来进行页面切换,只有一个入口Activity作为程序的启动Activity,其中有一个界面需要调用摄像头识别二维码, 于是就会用到Surfa ...

  7. 【转】Android中引入第三方Jar包的方法(java.lang.NoClassDefFoundError解决办法)

    原文网址:http://www.blogjava.net/anchor110/articles/355699.html 1.在工程下新建lib文件夹,将需要的第三方包拷贝进来.2.将引用的第三方包,添 ...

  8. HTML中的select下拉框内容显示不全的解决办法

    HTML中的select下拉框内容显示不全的解决办法 今天,我遇到这样一个问题:查询栏中的下拉框中的内容过长,导致部分被覆盖了. 查询了一些资料,有的说用函数控制,有的说用事件控制,有的看不懂,有的实 ...

  9. 代码漏洞扫描描述Cross Site History Manipulation解决办法[dongcoder.com]

    代码漏洞扫描 漏洞描述:Cross Site History Manipulation 简要描述:产品的行为差异或发送不同的反应,在某种程度上暴露了与安全性相关的产品状态,例如特定的操作是否成功.可能 ...

随机推荐

  1. JDK Linux下安装

    下载jdk-6u45-linux-x64.bin到/root目录下执行./jdk-6u45-linux-x64.bin 会在/root目录下生成 jdk1.6.0_45 文件 之后配置环境变量 编辑/ ...

  2. Educational Codeforces Round 61 (Rated for Div. 2)D(二分,模拟,思维)

    #include<bits/stdc++.h>using namespace std;typedef long long ll;int n,k;ll a[200007],b[200007] ...

  3. 前端的异步解决方案之Promise和Await-Async

    异步编程模式在前端开发过程中,显得越来越重要.从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的问题.随着ES6新标准的出来,处理异步数据流的解决方案又有了新的变化.Promise就是这其 ...

  4. socket套接字基本概念

    int socket()函数创建的是套接字socket,返回的是socket描述符(套接字描述符),其实就是文件描述符,socket(套接字)其实就是文件 socket()创建了套接字(文件),只是开 ...

  5. python安装出现的证书问题

    1. pip install pyenv 安装时出现下图错误 Could not install packages due to an EnvironmentError: HTTPSConnectio ...

  6. 项目笔记《DeepLung:Deep 3D Dual Path Nets for Automated Pulmonary Nodule Detection and Classification》(三)(下)结果评估

    在(上)中讲了如何得到csv文件并调用noduleCADEvaluationLUNA16.py求取froc值,这里就讲一讲froc值是如何求取的. annotations_filename = './ ...

  7. day13 内置函数二 递归,匿名函数,二分法

    .匿名函数(名字统一叫lambda) .语法 lambda 参数:返回值 .参数可以有多个,用逗号隔开 .只能写一行,执行结束后直接返回值 4返回值和正常函数一样,可以是任意值 .列: f=lambd ...

  8. layui的表单功能

    作为一个phper还是非常喜欢这个插件的~虽然在vue的群里面说这个插件好被人怼过..废话不多说, 这次使用到的是layui的表单功能.上次的日历忘记做笔记了非常可惜,大部分其实跟着文档撸就可以,这次 ...

  9. WebService、WCF、WebAPI、MVC的区别

    Web Service 1.它是基于SOAP协议的,数据格式是XML 2.只支持HTTP协议 3.它不是开源的,但可以被任意一个了解XML的人使用 4.它只能部署在IIS上 WCF 1.这个也是基于S ...

  10. 提取SQL中用到的表

    dos2unix * for i in `ls` do :}` awk '{print tolower($0)}' "${i}"|grep -Eiw "from" ...