JavaScript排序 — sort()方法 ——解決null、undefined、0之間的排序(混亂)問題 一、普通的數組排序 JavaScript中用方法sort()為數組排序。sort()方法有一個可選參數,是用來確定元素順序的函數。如果這個參數被省略,那麼數組中的元素將按照ASCII字 ...
此博客主要介紹JavaScript中sort()排序的使用方法,也進一步講述了:當排序的值存在null、undefined、0這三個特殊值時,解決排序混亂的方法,並結合自己的理解來闡述解決方法的原理。
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"]
備註:因為字母A、B的ASCII值分別為65、66,而a、b的值分別為97、98,所以上面輸出的結果是 ["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")));
重點:如果數組內某一對象為空值,排序是怎樣的呢?(顯然並不是按年齡順序排序的,因為存在null和undefined)
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的插值),同時我們又知道:當值為null、undefined、0時,這三者任意方式搭配相減,其結果都為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")));