资讯专栏INFORMATION COLUMN

记数组sort方法与字符串比较引起的Bug

wendux / 2585人阅读

摘要:发现的问题是字符串比较引起的。而在第二版的返回值是与,对应的是和。字符串比较是一个一个字符进行比较中方法的比较函数返回值正值,负值,的含义

前言

前几天使用JavaScript中Array的sort排序字符串,发现排序不准确,这里记一下。

第一版

</>复制代码

  1. var arr = ["0", "1", "11", "11", "2", "12", "123", "123", "333", "5"];
  2. // 第一个版本
  3. arr.sort(function(a, b) {
  4. return a > b;
  5. })
  6. console.log(arr); // ["0", "1", "11", "11", "12", "123", "123", "2", "333", "5"]
  7. // 这里发现结果不对,预想的结果是 ["0", "1", "2", "5", "11", "11", "12", "123", "123", "333"]

那就找原因。发现的问题是字符串比较引起的。

在JavaScript中,字符串的比较,是字符按从左到右一一对应比较的。如果两个字符串第一个字符是一样,就比较第二个字符,如果第二个相等,就比较第三个,以此类推,直到比较出结果。

而单个字符间比较的规则,这是是比较他们的charCode的大小。
列如:

</>复制代码

  1. "a".charCodeAt(0) // 97
  2. "b".charCodeAt(0) // 98
  3. "a" > "b" // false
第二版

明白了字符串比较的规则后, 就修改为下面的版本。

</>复制代码

  1. var arr = ["0", "1", "11", "11", "2", "12", "123", "123", "333", "5", "100"];
  2. // 第二个版本
  3. var isNumber = function(str) {
  4. // 前面说了是字符串类型,所以这里没有做类型判断
  5. return !isNaN(str);
  6. }
  7. // isNaN 这个方法需要注意, 会隐式的进行类型转, 需要注意
  8. // isNaN(null) => false, isNaN(true) => false, isNaN([]) => false
  9. arr.sort(function(a, b) {
  10. // 如果比较双方都是number类型的字符,按照number进行比较
  11. if(isNumber(a) && isNumber(b)) {
  12. // 隐式转换
  13. return a - b;
  14. }
  15. return a > b;
  16. })
第三版

字符里面全都是数字是没有问题了,但是还需要考虑非纯数字的情况

</>复制代码

  1. var arr = ["0", "1", "11", "11", "2", "12", "123", "123", "333", "5", "aa", "1aa"];
  2. // 从小到大
  3. var isNumber = function(str) {
  4. // 前面说了是字符串类型,所以这里没有做类型判断
  5. return !isNaN(str);
  6. }
  7. arr.sort(function(a, b) {
  8. // 如果比较双方都是number类型的字符,按照number进行比较
  9. if(isNumber(a) && isNumber(b)) {
  10. // 隐式转换
  11. return a - b;
  12. }
  13. return a > b;
  14. })
  15. // 输出结果 ["0", "1", "2", "5", "11", "11", "12", "123", "123", "1aa", "333", "aa"] 这个没有问题的
  16. // 从大到小
  17. var arr = ["0", "1", "11", "11", "2", "12", "123", "123", "333", "5", "aa", "1aa"];
  18. var isNumber = function(str) {
  19. // 前面说了是字符串类型,所以这里没有做类型判断
  20. return !isNaN(str);
  21. }
  22. arr.sort(function(a, b) {
  23. // 如果比较双方都是number类型的字符,按照number进行比较
  24. if(isNumber(a) && isNumber(b)) {
  25. // 隐式转换
  26. return b - a;
  27. }
  28. return b > a;
  29. })
  30. // 输出结果 ["123", "1aa", "aa", "5", "2", "333", "123", "12", "11", "11", "1", "0"] 已经是不符合期望

于是查找原因,发现原因是sort的比较方法的返回值不对。

如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
若 a 等于 b,则返回 0。
若 a 大于 b,则返回一个大于 0 的值。

而在第二版的返回值是true与false,对应的是 1 和 0。于是修改为下面的版本

</>复制代码

  1. var arr = ["0", "1", "11", "11", "2", "12", "123", "123", "333", "5", "aa", "1aa"];
  2. // 从大到小
  3. var isNumber = function(str) {
  4. // 前面说了是字符串类型,所以这里没有做类型判断
  5. return !isNaN(str);
  6. }
  7. arr.sort(function(a, b) {
  8. // 如果比较双方都是number类型的字符,按照number进行比较
  9. if(isNumber(a) && isNumber(b)) {
  10. // 隐式转换
  11. return b - a;
  12. }
  13. return b === a ? 0 : b > a ? 1 : -1;
  14. })
  15. // 输出结果["aa", "333", "1aa", "123", "123", "12", "11", "11", "5", "2", "1", "0"]
总结

在JS中字符串比较和sort进行排序不经常使用,使用的时候多测测。就能越过一些不必要的坑。

字符串比较是一个一个字符进行比较 Array中sort方法的比较函数返回值正值负值0的含义

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107653.html

相关文章

  • 前端实用资源整理

    摘要:事件的响应分区为三个阶段捕获目标冒泡阶段。绑定的多个事件会被覆盖,后者覆盖前者。再用转换成数值表示。如实际数量为,则展示为项目中使用过滤器做的处理可以抽取方法的,调整相关,可以获取指定位数的缩写。 CSS html5中a的download属性 定义和用法download 属性定义下载链接的地址或指定下载文件的名称。文件名称没有限定值,浏览器会自动在文件名称末尾添加该下载文件的后缀 (...

    Gu_Yan 评论0 收藏0
  • 前端实用资源整理

    摘要:事件的响应分区为三个阶段捕获目标冒泡阶段。绑定的多个事件会被覆盖,后者覆盖前者。再用转换成数值表示。如实际数量为,则展示为项目中使用过滤器做的处理可以抽取方法的,调整相关,可以获取指定位数的缩写。 CSS html5中a的download属性 定义和用法download 属性定义下载链接的地址或指定下载文件的名称。文件名称没有限定值,浏览器会自动在文件名称末尾添加该下载文件的后缀 (...

    wslongchen 评论0 收藏0
  • 这或许是东半球讲十大排序算法最好一篇文章

    摘要:希尔排序希尔排序这个名字,来源于它的发明者希尔,也称作缩小增量排序,是插入排序的一种更高效的改进版本。我们可以发现,当区间为的时候,它使用的排序方式就是插入排序。 冒泡排序 冒泡排序无疑是最为出名的排序算法之一,从序列的一端开始往另一端冒泡(你可以从左往右冒泡,也可以从右往左冒泡,看心情),依次比较相邻的两个数的大小(到底是比大还是比小也看你心情)。 showImg(https://s...

    wind3110991 评论0 收藏0
  • 基本排序 - Algorithms, Part I, week 2 ELEMENTARY SORTS

    摘要:我们讨论比较排序算法的理论基础,并结合本章应用排序和优先级队列算法。基本排序引入了选择排序,插入排序和。描述了,一种保证在线性时间内运行的排序算法。当我们后续实现排序算法时,我们实际上将这个机制隐藏在我们的实现下面。 前言 上一篇:栈和队列下一篇:归并排序 排序是重新排列一系列对象以便按照某种逻辑顺序排列的过程。排序在商业数据处理和现代科学计算中起着重要作用。在交易处理,组合优化,天体...

    BLUE 评论0 收藏0

发表评论

0条评论

wendux

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<