5

sort()排序方法—解决null、undefined、0之间的排序混乱问题

 1 year ago
source link: https://www.fly63.com/article/detial/12188
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

此博客主要介绍JavaScript中sort()排序的使用方法,也进一步讲述了:当排序的值存在null、undefined、0这三个特殊值时,解决排序混乱的方法,并结合自己的理解来阐述解决方法的原理。

一、普通的数组排序

JavaScript中用方法sort()为数组排序。sort()方法有一个可选参数,是用来确定元素顺序的函数。如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序。

数组元素是字符串

//定义新字符串元素数组
var arr = ["a", "b", "A", "B"];
//sort()方法排序
arr.sort();
console.log(arr);//["A", "B", "a", "b"]

 备注:因为字母AB的ASCII值分别为6566,而ab的值分别为9798,所以上面输出的结果是 ["A", "B", "a", "b"]。

数组元素是数字

//定义新数字元素数组
var arr = [15, 8, 25, 3];
//sort()方法排序
arr.sort();
console.log(arr);//[15, 25, 3, 8]

结果并不是我们想要的顺序(理想顺序:按数字大小排序)!原因如下:

sort()方法会对数组的每一项执行toString()方法,然后再对得到的字符串进行排序。所以之所以25比3大,但却排在3之前,是因为比较的是字符串25和字符串3。如果要得到我们理想的数据,则使用比较函数(通俗的说就是sort()方法内的参数)

比较函数的使用

//定义新数字元素数组
var arr = [15, 8, 25, 3];
//sort()方法排序
arr.sort((a,b)=>{
    //对数组进行遍历,通过比较a与b的差值大小,来排序
    return a-b;
});
console.log(arr);//[3, 8, 15, 25]

二、数组对象排序

其实和上文基本一致,只不过比较对象加了属性值

//定义数组对象
var arr=[{"age":24,name:'zs'},{"age":0,name:'ls'},{"age":7,name:'pl'}]
//sort()方法排序
arr.sort((a,b)=>{
    //对数组进行遍历,
    //通过对a对象的age属性与b对象的age属性
    //进行取差,根据插值大小,进而排序
    console.log(a['age']-b['age']);//-14 7 -17 7
    return a['age']-b['age'];
});
console.log(arr);//[{age: 0, name: 'ls'},{age: 7, name: 'pl'},{age: 24, name: 'zs'}]

对比较函数进行提取:

//定义数组对象
var arr=[{"age":24,name:'zs'},{"age":0,name:'ls'},{"age":7,name:'pl'}]
//将比较方法进行提取
var compare = function (obj1, obj2) {
    var val1 = obj1.age;
    var val2 = obj2.age;
    return val1 - val2;        
} 
//[{age: 0, name: 'ls'},{age: 7, name: 'pl'},{age: 24, name: 'zs'}]
console.log(arr.sort(compare));

对比较函数再进行改造,使得参数的输入更加灵活!

var arr=[{"age":24,name:'zs'},{"age":0,name:'ls'},{"age":7,name:'pl'}]
var compare = function (prop) {
    return function (obj1, obj2) {
        var val1 = obj1[prop];
        var val2 = obj2[prop];
        return val1 - val2         
    } 
}
//[{age: 0, name: 'ls'},{age: 7, name: 'pl'},{age: 24, name: 'zs'}]
console.log(arr.sort(compare("age")));

 重点:如果数组内某一对象为空值,排序是怎样的呢?(显然并不是按年龄顺序排序的,因为存在nullundefined)

var arr=[{"age":24,name:'zs'},{"age":0,name:'ls'},{"age":0,name:'gr'},
         {"age":null,name:'yo'},{"age":7,name:'pl'},{"age":undefined,name:'tt'},
         {"age":null,name:'jz'},{"age":0,name:'mn'},{"age":undefined,name:'we'}]

//[{"age": 0,"name": "ls"},{"age": 0,"name": "gr"},{"age": null,"name": "yo"},
//{"age": null,"name": "jz"},{"age": 0,"name": "mn"},{"age": 7,"name": "pl"},
//{"age": 24,"name": "zs"},{"age":undefined,"name": "tt"},
//{"age":undefined,"name": "we"}]
console.log(arr.sort(compare("age")));

我们可以知道上述比较函数是对比两个值的插值(可以是数字的插值,也可以是ASCII的插值),同时我们又知道:当值为nullundefined0时,这三者任意方式搭配相减,其结果都为0!,并且使用if判断都为false

解决办法:可以制造特殊值之间与特殊值与正常值之间的差足够大!

undefined - 所有值 = -9999 (也就是说undefined与其他值差的最多,排最小)
null - 所有值 = -999 (也就是说undefined与其他值差的第二多,排最第二小)
undefined - undefined = 0
null - null = 0
undefined - null = 0

上述说明是等式a - b 那么相反b - a规则也适用;也就是下文第二个if的返回值999 9999

-999和-9999、999,9999是用来区别其他差值的,也可根据实际情况进行差值设定

var arr=[{"age":24,name:'zs'},{"age":0,name:'ls'},{"age":0,name:'gr'},
         {"age":null,name:'yo'},{"age":7,name:'pl'},{"age":undefined,name:'tt'},
         {"age":null,name:'jz'},{"age":0,name:'mn'},{"age":undefined,name:'we'}]
var compare = function (prop) {
    return function (obj1, obj2) {
        var val1 = obj1[prop];
        var val2 = obj2[prop];
        if(!val1 && val1 != 0 && val2){
            //定义undefined特殊值的差值
	        if(val1 === undefined) return -9999
            //定义null特殊值的差值
	        return -999
	    }
	    if(!val2 && val2!= 0 && val1){
	        if(val2 === undefined) return 9999
	        return 999
	    }
	    return val1 - val2      
    } 
}
//[{age: undefined, name: 'we'},{age: undefined, name: 'tt'},{age: null, name: 'jz'},
//{age: null, name: 'yo'},{age: 0, name: 'ls'},{age: 0, name: 'gr'},
//{age: 0, name:'mn'},{age: 7, name: 'pl'},{age: 24, name: 'zs'}]
console.log(arr.sort(compare("age")));
来源:https://www.cnblogs.com/gby-web/p/16743564.html

链接: https://www.fly63.com/article/detial/12188


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK