【JavaScript排序】 sort()方法(解決null、undefined、0之間的排序(混亂)問題)

来源:https://www.cnblogs.com/gby-web/archive/2022/09/30/16743564.html
-Advertisement-
Play Games

此博客主要介紹JavaScript中sort()排序的使用方法,也進一步講述了:當排序的值存在null、undefined、0這三個特殊值時,解決排序混亂的方法,並結合自己的理解來闡述解決方法的原理。 JavaScript排序 — sort()方法 ——解決null、undefined、0之間的排序 ...


此博客主要介紹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"]

備註:因為字母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")));

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 現如今,手機錄屏是必不可少的能力之一。對於游戲領域作者來說,在平時直播玩游戲、製作攻略、操作集錦時,不方便切屏,這時在游戲內如果有一個錄製按鈕就可以隨時開啟,記錄下每個精彩瞬間,減少後期剪輯工作量;在直播App中開啟一鍵錄屏,不光方便主播後續的賬號運營與復盤,用戶也能隨時截取有意思的片段傳播在社交媒 ...
  • #背景 webpack構建過程中的hooks都有什麼呢?除了在網上看一些文章,還可以通過更直接的辦法,結合官方文檔快速讓你進入webpack的hook世界 寫一個入口文件 //index.js const webpack = require("webpack"); const path = requ ...
  • 語言基礎-變數 前言 從本篇博客開始 博主個人認為重要的知識點都會在在行前添加 ⭐ 來進行標識 變數 ECMASCRIPT變數是鬆散類型,意思是變數可以用於保存任何類型的數據。ECMASCRIPT中有三個關鍵字可以來聲明變數:var、let和const。 值得註意的是let和const只能在ES6以 ...
  • React Or Taro 項目配置Eslint校驗 一、下載Eslint相關deps依賴項; npm install --save-dev eslint-plugin-prettier eslint-plugin-jsx-a11y eslint-config-airbnb 註意:由於eslint- ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一.需求來源 今天碰到了一個需求,需要在頁面里,用水平瀑布流的方式,將一些圖片進行載入,這讓我突然想起我很久以前寫的一篇文章《JS兩種方式實現水平瀑布流佈局》 但是有個問題,這個需求是Vue項目的,那沒辦法,這裡給大家分享下我的開發過程, ...
  • 一、常見的圖片格式 BMP 是無損的、既支持索引色也支持直接色的點陣圖。這種圖片格式幾乎沒有對數據進行壓縮,所以BMP格式的圖片通常是較大的文件。 GIF 是無損的、採用索引色的點陣圖。採用LZW壓縮演算法進行編碼。文件小,是GIF格式的優點,同時,GIF格式還具有支持動畫以及透明的優點。但是GIF格 ...
  • 效果 之前: 之後 Code <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鳥教程(runoob.com)</title> </head> <body> <div class="rect"> <img src="https: ...
  • vue組件中最常見的數據傳遞就是父子組件之間的傳遞,父組件可以通過 props 向下傳數據給子組件,子組件可以通過 $emit 事件攜帶數據給父組件。然而當兩個頁面沒有任關係,該如何通信?這就引出了 EventBus ( 事件匯流排 ) 這個概念 初始化 方法一:新建文件 首先需要初始化一個 Even ...
一周排行
    -Advertisement-
    Play Games
  • JWT(JSON Web Token)是一種用於在網路應用之間傳遞信息的開放標準(RFC 7519)。它使用 JSON 對象在安全可靠的方式下傳遞信息,通常用於身份驗證和信息交換。 在Web API中,JWT通常用於對用戶進行身份驗證和授權。當用戶登錄成功後,伺服器會生成一個Token並返回給客戶端 ...
  • 老周在幾個世紀前曾寫過樹莓派相關的 iOT 水文,之所以沒寫 Nano Framework 相關的內容,是因為那時候這貨還不成熟,可玩性不高。不過,這貨現在已經相對完善,老周都把它用在項目上了——第一個是自製的智能插座,這個某寶上50多塊可以買到,搜“esp32 插座”就能找到。一種是 86 型盒子 ...
  • 引言 上一篇我們創建了一個Sample.Api項目和Sample.Repository,並且帶大家熟悉了一下Moq的概念,這一章我們來實戰一下在xUnit項目使用依賴註入。 Xunit.DependencyInjection Xunit.DependencyInjection 是一個用於 xUnit ...
  • 在 Avalonia 中,樣式是定義控制項外觀的一種方式,而控制項主題則是一組樣式和資源,用於定義應用程式的整體外觀和感覺。本文將深入探討這些概念,並提供示例代碼以幫助您更好地理解它們。 樣式是什麼? 樣式是一組屬性,用於定義控制項的外觀。它們可以包括背景色、邊框、字體樣式等。在 Avalonia 中,樣 ...
  • 在處理大型Excel工作簿時,有時候我們需要在工作表中凍結窗格,這樣可以在滾動查看數據的同時保持某些行或列固定不動。凍結窗格可以幫助我們更容易地導航和理解複雜的數據集。相反,當你不需要凍結窗格時,你可能需要解凍它們以獲得完整的視野。 下麵將介紹如何使用免費.NET庫通過C#實現凍結Excel視窗以鎖 ...
  • .NET 部署 IIS 的簡單步驟一: 下載 dotnet-hosting-x.y.z-win.exe ,下載地址:.NET Downloads (Linux, macOS, and Windows) (microsoft.com) .NET 部署 IIS 的簡單步驟二: 選擇對應的版本,點擊進入詳 ...
  • 拓展閱讀 資料庫設計工具-08-概覽 資料庫設計工具-08-powerdesigner 資料庫設計工具-09-mysql workbench 資料庫設計工具-10-dbdesign 資料庫設計工具-11-dbeaver 資料庫設計工具-12-pgmodeler 資料庫設計工具-13-erdplus ...
  • 初識STL STL,(Standard Template Library),即"標準模板庫",由惠普實驗室開發,STL中提供了非常多對信息學奧賽很有用的東西。 vector vetor是STL中的一個容器,可以看作一個不定長的數組,其基本形式為: vector<數據類型> 名字; 如: vector ...
  • 前言 最近自己做了個 Falsk 小項目,在部署上伺服器的時候,發現雖然不乏相關教程,但大多都是將自己項目代碼複製出來,不講核心邏輯,不太簡潔,於是將自己部署的經驗寫成內容分享出來。 uWSGI 簡介 uWSGI: 一種實現了多種協議(包括 uwsgi、http)並能提供伺服器搭建功能的 Pytho ...
  • 1 文本Embedding 將整個文本轉化為實數向量的技術。 Embedding優點是可將離散的詞語或句子轉化為連續的向量,就可用數學方法來處理詞語或句子,捕捉到文本的語義信息,文本和文本的關係信息。 ◉ 優質的Embedding通常會讓語義相似的文本在空間中彼此接近 ◉ 優質的Embedding相 ...