js?Array?sort實戰(zhàn)排序全面講解教程
一、sort()方法基礎(chǔ)認(rèn)知
1. 基本定義
sort() 是 JavaScript 數(shù)組原型上的內(nèi)置方法,用于對數(shù)組元素進(jìn)行排序,并返回排序后的原數(shù)組(注意:它是「原地排序」,會直接修改原始數(shù)組,而非返回新數(shù)組)。
2. 默認(rèn)排序規(guī)則
sort() 方法如果不傳入任何參數(shù),會按照「字符串 Unicode 編碼」進(jìn)行排序,而非我們直覺中的數(shù)字大小排序,這是新手最容易踩坑的點。
示例:默認(rèn)排序的表現(xiàn)
// 1. 字符串?dāng)?shù)組(符合直覺,按Unicode排序) const strArr = ["banana", "apple", "cherry", "Abc"]; strArr.sort(); console.log(strArr); // ["Abc", "apple", "banana", "cherry"] // 原因:Unicode 中大寫字母編碼(A-Z:65-90)小于小寫字母(a-z:97-122) // 2. 數(shù)字?jǐn)?shù)組(不符合直覺,按字符串Unicode排序) const numArr = [10, 2, 31, 4, 25]; numArr.sort(); console.log(numArr); // [10, 2, 25, 31, 4] // 原因:數(shù)字會被先轉(zhuǎn)為字符串,"10"的Unicode編碼小于"2",因此10排在2前面
二、sort()核心:比較函數(shù)(compareFunction)
要實現(xiàn)按數(shù)字大小、對象屬性等自定義規(guī)則排序,必須給 sort() 傳入一個比較函數(shù)((a, b) => {}),這是 sort() 方法的靈魂。
1. 比較函數(shù)的參數(shù)與返回值規(guī)則
比較函數(shù)接收兩個必選參數(shù) a 和 b(代表數(shù)組中任意兩個待比較的元素,a 是后一個元素,b 是前一個元素),返回值的類型決定了排序結(jié)果:
| 比較函數(shù)返回值 | 排序規(guī)則 |
|---|---|
返回 負(fù)數(shù)(< 0) | a 排在 b 前面(升序邏輯) |
| 返回 0 | a 和 b 位置不變(穩(wěn)定排序的關(guān)鍵) |
返回 正數(shù)(> 0) | a 排在 b 后面(降序邏輯) |
2. 數(shù)字?jǐn)?shù)組的正/降序排序(最常用場景)
(1)數(shù)字升序排序
const numArr = [10, 2, 31, 4, 25]; // 比較函數(shù):a - b 實現(xiàn)升序 numArr.sort((a, b) => a - b); console.log(numArr); // [2, 4, 10, 25, 31] // 原理:若a < b,a - b為負(fù)數(shù),a排在b前面;若a > b,a - b為正數(shù),a排在b后面
(2)數(shù)字降序排序
const numArr = [10, 2, 31, 4, 25]; // 比較函數(shù):b - a 實現(xiàn)降序 numArr.sort((a, b) => b - a); console.log(numArr); // [31, 25, 10, 4, 2] // 原理:若b > a,b - a為正數(shù),a排在b后面(即大的數(shù)排在前面)
三、常見場景實戰(zhàn)排序
1. 字符串?dāng)?shù)組:忽略大小寫排序
默認(rèn)排序會區(qū)分大小寫,通過將元素統(tǒng)一轉(zhuǎn)為大寫/小寫后比較,可實現(xiàn)忽略大小寫的排序:
const strArr = ["banana", "Apple", "cherry", "abc"];
strArr.sort((a, b) => {
const lowerA = a.toLowerCase();
const lowerB = b.toLowerCase();
if (lowerA < lowerB) return -1; // 升序
if (lowerA > lowerB) return 1;
return 0;
});
console.log(strArr); // ["Apple", "abc", "banana", "cherry"]
2. 字符串?dāng)?shù)組:按長度排序
const strArr = ["banana", "apple", "cherry", "a"];
// 先按長度升序,長度相同按Unicode升序
strArr.sort((a, b) => {
if (a.length !== b.length) {
return a.length - b.length; // 長度升序
}
return a.localeCompare(b); // 長度相同,按自然語言排序(比直接比較字符串更友好)
});
console.log(strArr); // ["a", "apple", "banana", "cherry"]
3. 對象數(shù)組:按單個屬性排序
日常開發(fā)中最常用的場景,比如按用戶年齡、商品價格排序:
// 用戶數(shù)組
const users = [
{ name: "張三", age: 25, salary: 8000 },
{ name: "李四", age: 20, salary: 10000 },
{ name: "王五", age: 30, salary: 7000 },
];
// (1)按年齡升序排序
users.sort((a, b) => a.age - b.age);
console.log(users.map(u => u.name)); // ["李四", "張三", "王五"]
// (2)按薪資降序排序
users.sort((a, b) => b.salary - a.salary);
console.log(users.map(u => u.name)); // ["李四", "張三", "王五"]
// (3)按姓名自然語言排序(中文排序)
users.sort((a, b) => a.name.localeCompare(b.name, "zh-CN"));
console.log(users.map(u => u.name)); // ["李四", "王五", "張三"]
4. 對象數(shù)組:多條件排序
當(dāng)?shù)谝粋€排序條件相同時,按第二個條件排序(比如:先按年齡升序,年齡相同按薪資降序):
const users = [
{ name: "張三", age: 25, salary: 8000 },
{ name: "李四", age: 20, salary: 10000 },
{ name: "趙六", age: 25, salary: 9000 },
{ name: "王五", age: 30, salary: 7000 },
];
users.sort((a, b) => {
// 第一個條件:年齡升序
if (a.age !== b.age) {
return a.age - b.age;
}
// 第二個條件:薪資降序(年齡相同時生效)
return b.salary - a.salary;
});
console.log(users.map(u => `${u.name}(${u.age}歲,${u.salary}元)`));
// 輸出:
// ["李四(20歲,10000元)", "趙六(25歲,9000元)", "張三(25歲,8000元)", "王五(30歲,7000元)"]
5. 包含特殊值(null/undefined)的數(shù)組排序
sort() 會自動將 undefined 排到數(shù)組末尾;null 轉(zhuǎn)為數(shù)字是 0,可手動處理其排序位置:
const mixedArr = [10, null, 5, undefined, 3, null, 8];
mixedArr.sort((a, b) => {
// 處理undefined:直接排到末尾
if (a === undefined) return 1;
if (b === undefined) return -1;
// 處理null:按0參與數(shù)字升序排序
return (a ?? 0) - (b ?? 0);
});
console.log(mixedArr); // [null, null, 3, 5, 8, 10, undefined]
四、進(jìn)階知識點:穩(wěn)定排序
1. 穩(wěn)定排序的定義
如果數(shù)組中兩個相等的元素(按比較函數(shù)判斷返回 0),在排序前后的相對位置保持不變,這種排序就是「穩(wěn)定排序」。
2.sort()的穩(wěn)定性
- ES6(ECMAScript 2015)及以后:
sort()方法實現(xiàn)了穩(wěn)定排序(不同瀏覽器內(nèi)核實現(xiàn)一致)。 - ES6 之前:
sort()是不穩(wěn)定排序,不同瀏覽器表現(xiàn)可能不同。
示例:驗證穩(wěn)定排序
// 商品數(shù)組:按價格升序(價格相同的商品,保持原有相對位置)
const goods = [
{ name: "商品A", price: 50 },
{ name: "商品B", price: 30 }, // 先出現(xiàn)
{ name: "商品C", price: 50 },
{ name: "商品D", price: 30 }, // 后出現(xiàn)
];
// 按價格升序排序
goods.sort((a, b) => a.price - b.price);
console.log(goods.map(g => g.name)); // ["商品B", "商品D", "商品A", "商品C"]
// 結(jié)果:價格30的商品B仍在商品D前面,價格50的商品A仍在商品C前面,驗證了穩(wěn)定排序
五、常見誤區(qū)與避坑技巧
1. 誤區(qū)1:忽略「原地排序」,誤認(rèn)返回新數(shù)組
sort() 會修改原始數(shù)組,返回的是原始數(shù)組的引用,而非新數(shù)組。如果需要保留原始數(shù)組,應(yīng)先拷貝數(shù)組再排序。
避坑示例:
const originalArr = [10, 2, 31]; // 先拷貝數(shù)組(推薦使用擴(kuò)展運(yùn)算符或slice(),淺拷貝即可) const sortedArr = [...originalArr].sort((a, b) => a - b); console.log(originalArr); // [10, 2, 31](原始數(shù)組未被修改) console.log(sortedArr); // [2, 10, 31](排序后的新數(shù)組)
2. 誤區(qū)2:數(shù)字排序不傳入比較函數(shù)
新手常直接對數(shù)字?jǐn)?shù)組使用 sort(),導(dǎo)致排序結(jié)果不符合預(yù)期,必須傳入 (a, b) => a - b(升序)或 (a, b) => b - a(降序)。
3. 誤區(qū)3:比較函數(shù)返回非數(shù)字類型
比較函數(shù)的返回值應(yīng)是數(shù)字(負(fù)數(shù)/0/正數(shù)),若返回布爾值或其他類型,會被隱式轉(zhuǎn)為數(shù)字(true→1,false→0),可能導(dǎo)致排序異常。
錯誤示例 vs 正確示例:
const numArr = [10, 2, 31]; // 錯誤:返回布爾值,排序結(jié)果不可靠 numArr.sort((a, b) => a > b); // 正確:返回數(shù)字,排序結(jié)果穩(wěn)定 numArr.sort((a, b) => a - b);
4. 誤區(qū)4:中文排序直接使用字符串比較
直接用 a > b 比較中文,會按 Unicode 編碼排序,不符合中文的拼音/筆畫排序邏輯,應(yīng)使用 localeCompare() 并指定中文環(huán)境。
正確示例:中文拼音排序
const chineseArr = ["張三", "李四", "王五", "趙六"];
// localeCompare("zh-CN"):按中文拼音排序
chineseArr.sort((a, b) => a.localeCompare(b, "zh-CN"));
console.log(chineseArr); // ["李四", "王五", "張三", "趙六"]
六、sort()方法的性能說明
sort() 的底層排序算法并非固定(由瀏覽器內(nèi)核實現(xiàn)):
- Chrome/V8 引擎:對于小型數(shù)組(長度≤22)使用「插入排序」,大型數(shù)組使用「快速排序的變種(TimSort/QuickSort)」,平均時間復(fù)雜度為
O(n log n)。 - Firefox 引擎:使用「歸并排序」,時間復(fù)雜度
O(n log n)。
日常開發(fā)中無需關(guān)注底層實現(xiàn),只需關(guān)注排序規(guī)則和穩(wěn)定性即可,其性能足以滿足絕大多數(shù)業(yè)務(wù)場景。
總結(jié)
sort()是原地排序方法,會修改原始數(shù)組,需保留原數(shù)組時應(yīng)先拷貝([...arr]/arr.slice())。- 默認(rèn)按字符串 Unicode 排序,數(shù)字/對象排序必須傳入比較函數(shù),核心規(guī)則是「返回負(fù)數(shù)a在前、返回正數(shù)a在后、返回0位置不變」。
- 常見場景:數(shù)字正/降序(
a-b/b-a)、對象多條件排序、中文排序(localeCompare("zh-CN"))。 - ES6 及以后
sort()是穩(wěn)定排序,特殊值(undefined)默認(rèn)排末尾,使用時需規(guī)避非數(shù)字返回值等誤區(qū)。
到此這篇關(guān)于js Array sort實戰(zhàn)排序全面講解教程的文章就介紹到這了,更多相關(guān)js Array sort排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序如何刷新當(dāng)前界面的實現(xiàn)方法
這篇文章主要介紹了微信小程序如何刷新當(dāng)前界面的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用小程序具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
js判斷當(dāng)前頁面在移動設(shè)備還是在PC端中打開
這篇文章主要介紹了js判斷當(dāng)前頁面在移動設(shè)備還是在PC端中打開的相關(guān)資料,需要的朋友可以參考下2016-01-01
JS實現(xiàn)數(shù)組去重及數(shù)組內(nèi)對象去重功能示例
這篇文章主要介紹了JS實現(xiàn)數(shù)組去重及數(shù)組內(nèi)對象去重功能,結(jié)合實例形式分析了ES5與ES6兩種版本針對數(shù)組去重的相關(guān)操作技巧,需要的朋友可以參考下2019-02-02

