js中的數(shù)組對(duì)象排序分析
一、普通數(shù)組排序
js中用方法sort()為數(shù)組排序。sort()方法有一個(gè)可選參數(shù),是用來(lái)確定元素順序的函數(shù)。如果這個(gè)參數(shù)被省略,那么數(shù)組中的元素將按照ASCII字符順序進(jìn)行排序。如:
var arr = ["a", "b", "A", "B"]; arr.sort(); console.log(arr);//["A", "B", "a", "b"]
因?yàn)樽帜窤、B的ASCII值分別為65、66,而a、b的值分別為97、98,所以上面輸出的結(jié)果是 ["A", "B", "a", "b"] 。
如果數(shù)組元素是數(shù)字呢,結(jié)果會(huì)是怎樣?
var arr = [15, 8, 25, 3]; arr.sort(); console.log(arr);//[15, 25, 3, 8]
結(jié)果是 [15, 25, 3, 8] 。其實(shí),sort方法會(huì)調(diào)用每個(gè)數(shù)組項(xiàng)的toString()方法,得到字符串,然后再對(duì)得到的字符串進(jìn)行排序。雖然數(shù)值15比3大,但在進(jìn)行字符串比較時(shí)"15"則排在"3"前面。顯然,這種結(jié)果不是我們想要的,這時(shí),sort()方法的參數(shù)就起到了作用,我們把這個(gè)參數(shù)叫做比較函數(shù)。
比較函數(shù)接收兩個(gè)參數(shù),如果第一個(gè)參數(shù)應(yīng)該位于第二個(gè)之前則返回一個(gè)負(fù)數(shù),如果兩個(gè)參數(shù)相等則返回0,如果第一個(gè)參數(shù)應(yīng)該位于第二個(gè)之后則返回一個(gè)正數(shù)。例子:
var arr = [23, 9, 4, 78, 3]; var compare = function (x, y) {//比較函數(shù) if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; } } console.log(arr.sort(compare));
結(jié)果為 [3, 4, 9, 23, 78] ,返回了我們想要的結(jié)果。如果要按降序排序,比較函數(shù)寫成這樣即可:
var compare = function (x, y) { if (x < y) { return 1; } else if (x > y) { return -1; } else { return 0; } }
我們并不能用比較函數(shù)比較一個(gè)不能轉(zhuǎn)化為數(shù)字的字符串與數(shù)字的順序:
var arr = ["b", 5];
console.log(arr.sort(compare))
結(jié)果是 ["b", 5] 。因?yàn)楸容^函數(shù)在比較時(shí),會(huì)把先把字符串轉(zhuǎn)化為數(shù)字,然后再比較,字符串b不能轉(zhuǎn)化為數(shù)字,所以就不能比較大小。然而,當(dāng)不用比較函數(shù)時(shí),會(huì)比較ASCII值,所以結(jié)果是 [5, "b"] 。
二、數(shù)組對(duì)象排序
如果數(shù)組項(xiàng)是對(duì)象,我們需要根據(jù)數(shù)組項(xiàng)的某個(gè)屬性對(duì)數(shù)組進(jìn)行排序,要怎么辦呢?其實(shí)和前面的比較函數(shù)也差不多:
var arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}]; var compare = function (obj1, obj2) { var val1 = obj1.name; var val2 = obj2.name; if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } console.log(arr.sort(compare));
輸出結(jié)果為 [Object { name="wlz", age=25}, Object { name="zlw", age=24}] ,可以看到數(shù)組已經(jīng)按照 name 屬性進(jìn)行了排序。我們可以對(duì)上面的比較函數(shù)再改造一下:
var compare = function (prop) { return function (obj1, obj2) { var val1 = obj1[prop]; var val2 = obj2[prop];if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } }
如果想按照 age 進(jìn)行排序, arr.sort(compare("age")) 即可。
但是對(duì)age屬性進(jìn)行排序時(shí)需要注意了,如果age屬性的值是數(shù)字,那么排序結(jié)果會(huì)是我們想要的。但很多時(shí)候我們從服務(wù)器傳回來(lái)的數(shù)據(jù)中,屬性值通常是字符串?,F(xiàn)在我把上面的數(shù)組改為:
var arr = [{name: "zlw", age: "24"}, {name: "wlz", age: "5"}];
可以看到,我把 age 屬性由數(shù)字改為了字符串,第二個(gè)數(shù)組項(xiàng)的 age 值改為了 "5" 。再次調(diào)用 arr.sort(compare("age")) 后,結(jié)果為:
[Object { name="zlw", age="24"}, Object { name="wlz", age="5"}]
我們的期望是5排在25前面,但是結(jié)果不是。這是因?yàn)楫?dāng)兩個(gè)數(shù)字字符串比較大小時(shí),會(huì)比較它們的ASCII值大小,比較規(guī)則是:從第一個(gè)字符開(kāi)始,順次向后直到出現(xiàn)不同的字符為止,然后以第一個(gè)不同的字符的ASCII值確定大小。所以"24"與"5"比較大小時(shí),先比較”2“與"5"的ASCII值,顯然”2“的ASCII值比"5"小,即確定排序順序。
現(xiàn)在,我們需要對(duì)比較函數(shù)再做一些修改:
var compare = function (prop) { return function (obj1, obj2) { var val1 = obj1[prop]; var val2 = obj2[prop]; if (!isNaN(Number(val1)) && !isNaN(Number(val2))) { val1 = Number(val1); val2 = Number(val2); } if (val1 < val2) { return -1; } else if (val1 > val2) { return 1; } else { return 0; } } }
在比較函數(shù)中,先把比較屬性值轉(zhuǎn)化為數(shù)字 Number(val1) 再通過(guò) !isNaN(Number(val1)) 判斷轉(zhuǎn)化后的值是不是數(shù)字(有可能是NaN),轉(zhuǎn)化后的值如果是數(shù)字,則比較轉(zhuǎn)換后的值,這樣就可以得到我們想要的結(jié)果了, 調(diào)用 arr.sort(compare("age")) 得到:
[Object { name="wlz", age="5"}, Object { name="zlw", age="24"}]
可以看到,確實(shí)是按正確的方式排序了。
這篇文章所講的都是基礎(chǔ)的,沒(méi)什么技術(shù)含量,只是最近項(xiàng)目中遇到了對(duì)數(shù)組對(duì)象進(jìn)行排序的問(wèn)題,所以在這里寫出來(lái)分享一下,相信總能幫到一些朋友。
- JS對(duì)象數(shù)組排序方法測(cè)試代碼示例
- JavaScript將對(duì)象數(shù)組按字母順序排序的方法詳解
- JavaScript中好用的數(shù)組對(duì)象排序方法分享
- javascript中的Array對(duì)象(數(shù)組的合并、轉(zhuǎn)換、迭代、排序、堆棧)
- JS sort方法基于數(shù)組對(duì)象屬性值排序
- JS深入學(xué)習(xí)之?dāng)?shù)組對(duì)象排序操作示例
- js 根據(jù)對(duì)象數(shù)組中的屬性進(jìn)行排序?qū)崿F(xiàn)代碼
- JS實(shí)現(xiàn)給數(shù)組對(duì)象排序的方法分析
- JS實(shí)現(xiàn)根據(jù)數(shù)組對(duì)象的某一屬性排序操作示例
- JS實(shí)現(xiàn)json對(duì)象數(shù)組按對(duì)象屬性排序操作示例
- JavaScripts數(shù)組里的對(duì)象排序的24個(gè)方法(最新整理收藏)
相關(guān)文章
Taro小程序自定義頂部導(dǎo)航欄功能的實(shí)現(xiàn)
這篇文章主要介紹了Taro小程序自定義頂部導(dǎo)航欄功能的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12js循環(huán)動(dòng)態(tài)綁定帶參數(shù)函數(shù)遇到的問(wèn)題及解決方案[轉(zhuǎn)]
關(guān)于Javascript利用循環(huán)綁定事件的例子,需要的朋友可以參考下。2010-11-11pnpm?monorepo?聯(lián)調(diào)方案問(wèn)題解析
文章主要介紹了在pnpmmonorepo環(huán)境下進(jìn)行多庫(kù)聯(lián)調(diào)的方案,包括使用`pnpmlink`命令來(lái)鏈接指定的文件夾或全局的`node_modules`,并在項(xiàng)目中通過(guò)`pnpmlink--global<pkg>`來(lái)引用這些庫(kù),本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-12-12JavaScript前端控制網(wǎng)絡(luò)并發(fā)數(shù)目的常見(jiàn)方法小結(jié)
控制前端發(fā)起請(qǐng)求的并發(fā)數(shù),即限制同一時(shí)間內(nèi)進(jìn)行處理的請(qǐng)求數(shù)量,是一種有效的策略,本文將詳細(xì)介紹前端控制并發(fā)數(shù)的幾種常見(jiàn)做法,希望對(duì)大家有所幫助2023-12-12jscript之Read an Excel Spreadsheet
jscript之Read an Excel Spreadsheet...2007-06-06JS實(shí)現(xiàn)的鼠標(biāo)跟隨代碼(卡通手型點(diǎn)擊效果)
這篇文章主要介紹了JS實(shí)現(xiàn)的鼠標(biāo)跟隨代碼,帶有卡通手型點(diǎn)擊效果.涉及JavaScript鼠標(biāo)事件的響應(yīng)與頁(yè)面元素的動(dòng)態(tài)調(diào)用技巧,需要的朋友可以參考下2015-10-10原生JavaScript實(shí)現(xiàn)五子棋游戲
這篇文章主要為大家詳細(xì)介紹了原生JavaScript實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11原生JS封裝拖動(dòng)驗(yàn)證滑塊的實(shí)現(xiàn)代碼示例
這篇文章主要介紹了原生JS封裝拖動(dòng)驗(yàn)證滑塊的實(shí)現(xiàn)代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06