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

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

大家好,又见面了,我是全栈君。

前言

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

第一版

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

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

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

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

'a'.charCodeAt(0) //  97
'b'.charCodeAt(0) // 98
'a' > 'b' // false

第二版

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

var arr = ['0', '1', '11', '11',  '2', '12', '123', '123', '333', '5', '100'];
// 第二个版本
var isNumber = function(str) {
    // 前面说了是字符串类型,所以这里没有做类型判断
    return !isNaN(str);
}
// isNaN 这个方法需要注意, 会隐式的进行类型转, 需要注意
// isNaN(null) => false, isNaN(true) => false, isNaN([]) => false 

arr.sort(function(a, b) {
// 如果比较双方都是number类型的字符,按照number进行比较 
    if(isNumber(a) && isNumber(b)) {
        // 隐式转换
        return a - b;
    }
    return a > b;
})

第三版

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

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


// 从大到小
var arr = ['0', '1', '11', '11',  '2', '12', '123', '123', '333', '5', 'aa', '1aa'];
var isNumber = function(str) {
    // 前面说了是字符串类型,所以这里没有做类型判断
    return !isNaN(str);
}
arr.sort(function(a, b) {
// 如果比较双方都是number类型的字符,按照number进行比较 
    if(isNumber(a) && isNumber(b)) {
        // 隐式转换
        return b - a;
    }
    return b > a;
})
// 输出结果 ["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。于是修改为下面的版本

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

总结

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

字符串比较是一个一个字符进行比较

Array中sort方法的比较函数返回值正值负值0的含义

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107638.html原文链接:https://javaforall.net

(0)
上一篇 2022年3月13日 下午5:35
下一篇 2022年3月13日 下午5:35


相关推荐

  • Apache 服务器和Tomcat 服务器的区别

    Apache 服务器和Tomcat 服务器的区别nbsp nbsp nbsp nbsp 最近工作总是接触到 Apache 和 Tomcat 服务器 它们到底有什么区别 还是有点模糊 下面梳理一下 nbsp nbsp nbsp nbsp Apache 是 Web 服务器 静态解析 如 HTML Tomcat 是 Java 应用服务器 动态解析 如 JSP 请参考 web 服务器与应用服务器的区别 nbsp nbsp nbsp nbsp Tomcat 是一个 Servlet JSP 容器 是 Apache 的扩展 可以独立于 Apache

    2026年3月16日
    2
  • Python浪漫表白源码(附带详细教程)

    Python浪漫表白源码(附带详细教程)      要知道我们程序猿也是需要浪漫的,小博我之前在网上搜寻了很多代码缺发现好多都不是最新的,所以自己就整理了一下代码,现在与广大博友们分享下我们需要用到的包使用pipinstall+(包名)turtle2.random程序源码#ProjectLeader:刘#Project:表白源码

    2022年5月29日
    50
  • 网页网游的外挂实现与分析 之 开心网外挂实现

    网页网游的外挂实现与分析 之 开心网外挂实现     关于网页网游大家应该已经有所感受了。现在最火的莫过于kaixin001的种菜养动物了。大家偷菜种菜乐此不疲。不过怎么才能自动的进行偷菜呢?我自己简单的分析了一下,并实现了一个kaixin001菜地杀手。一下简述了从分析到开发的整个过程。虽然没有将所有代码都分享出来,但是下边的分析足够大家写一个类似的程序了。大家可以去http://orion.zhangle.googlepages.

    2025年8月31日
    8
  • Centos7部署mysql5.7

    Centos7部署mysql5.7下载mysql源安装包wgethttp://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm如果官网下载地址有问题也可以使用博客地址下载,下载后上传至服务器即可https://download.csdn.net/download/wu2700222/10460468安装mysql源yumlocalinstall…

    2022年7月16日
    17
  • 三星刷机工具Odin图文刷机教程

    三星刷机工具Odin图文刷机教程解压完,双击安装包选择语言,语言栏选择simplifiedCinnese国家选择c朱雀网络www.zhuquewl.comROM包下载hina安装路径可选择其他驱动盘,或者直接安装亦可注意事项: 1)手机电池有个一半的电量或是更少点都没问题,反正不要刷机过程中没电就行。真是没电了,也没事,充电,重刷就行了。2)给手机做好备份。3)下载刷机包,就自己准备着下载。4)下载刷机工具,

    2022年7月21日
    20
  • pycharm 查找替换_word查找和替换功能可以实现

    pycharm 查找替换_word查找和替换功能可以实现方法一:快捷键:ctr(control)+shift+r(replace:替换)方法二:

    2022年8月25日
    10

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号