JavaScript Sort 的一個(gè)錯(cuò)誤用法示例
前不久同事的代碼中出了一個(gè)很神奇的問(wèn)題,大致流程是對(duì)一個(gè)由對(duì)象組成的數(shù)組進(jìn)行排序,其中屬性 a 用于排序,屬性 b 作為一個(gè)優(yōu)選條件,當(dāng) b 等于 1 的時(shí)候無(wú)論 a 值是什么,都排在開頭 。這本是一個(gè)很簡(jiǎn)單的問(wèn)題,問(wèn)題就在于他用兩次 sort 實(shí)現(xiàn)在這次排序,先根據(jù) a 的屬性排序,然后再根據(jù) b 的值來(lái)排序。問(wèn)題就出在第二次排序中。
我們想當(dāng)然的會(huì)認(rèn)為在第一次排序中,數(shù)組已經(jīng)根據(jù) a 的屬性由大到小排序,在第二次中我們只要不去動(dòng)原數(shù)組的順序就行(一般在方法中寫成返回0或-1),只考慮單獨(dú)把 b 等于 1 的元素提到前面去。但是其實(shí)這與語(yǔ)言所選用的排序算法有關(guān),javascript (和一起其他語(yǔ)言)內(nèi)置的 sort 方法采用的是幾種排序算法的集合,有時(shí)并不能保證相同元素的位置保持一致。
下面是從 stackoverflow 上面找來(lái)的一個(gè)例子
var arrayToSort = [
{name: 'a', strength: 1}, {name: 'b', strength: 1}, {name: 'c', strength: 1}, {name: 'd', strength: 1},
{name: 'e', strength: 1}, {name: 'f', strength: 1}, {name: 'g', strength: 1}, {name: 'h', strength: 1},
{name: 'i', strength: 1}, {name: 'j', strength: 1}, {name: 'k', strength: 1}, {name: 'l', strength: 1},
{name: 'm', strength: 1}, {name: 'n', strength: 1}, {name: 'o', strength: 1}, {name: 'p', strength: 1},
{name: 'q', strength: 1}, {name: 'r', strength: 1}, {name: 's', strength: 1}, {name: 't', strength: 1}
];
arrayToSort.sort(function (a, b) {
return b.strength - a.strength;
});
arrayToSort.forEach(function (element) {
console.log(element.name);
});
我們會(huì)以為最后元素的值還是從 a 到 t,但實(shí)際運(yùn)行下來(lái)的結(jié)果卻是亂序的,這是因?yàn)?sort 的算法并沒(méi)有保留原數(shù)組的順序,也即 unstable。
那么我們就該盡量避免這種情況發(fā)生,就我同事的例子,將兩次 sort 的邏輯合并在一次中應(yīng)該是個(gè)可行的辦法,如果必須分為多次 sort,那么就把原數(shù)組的順序記錄在元素的屬性上把。
相關(guān)文章
javascript實(shí)現(xiàn)鏈接單選效果的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)鏈接單選效果的方法,可實(shí)現(xiàn)點(diǎn)擊鏈接改變其背景色的功能,同時(shí)可禁用對(duì)應(yīng)鏈接的跳轉(zhuǎn),需要的朋友可以參考下2015-05-05JavaScript對(duì)象解構(gòu)的用法實(shí)例解析
解構(gòu)賦值允許你使用類似數(shù)組或?qū)ο笞置媪康恼Z(yǔ)法將數(shù)組和對(duì)象的屬性賦給各種變量,下面這篇文章主要給大家介紹了關(guān)于JavaScript對(duì)象解構(gòu)用法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01詳解js模板引擎art template數(shù)組渲染的方法
art-template 是一個(gè)簡(jiǎn)約、超快的模板引擎。這篇文章主要介紹了詳解js模板引擎art template數(shù)組渲染的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10JavaScript實(shí)現(xiàn)MD5加密的六種方式實(shí)例
這篇文章主要給大家介紹了關(guān)于JavaScript實(shí)現(xiàn)MD5加密的六種方式,在JS中可以實(shí)現(xiàn)MD5加密算法,可以使用第三方庫(kù)或者自己編寫代碼實(shí)現(xiàn),需要的朋友可以參考下2023-09-09微信小程序?qū)W習(xí)(4)-系統(tǒng)配置app.json詳解
我們使用app.json文件來(lái)對(duì)微信小程序進(jìn)行全局配置,決定頁(yè)面文件的路徑、窗口表現(xiàn)、設(shè)置網(wǎng)絡(luò)超時(shí)時(shí)間、設(shè)置多 tab 等。2017-01-01js如何監(jiān)聽(tīng)input輸入事件及使用防抖封裝函數(shù)處理方法
這篇文章主要給大家介紹了關(guān)于js如何監(jiān)聽(tīng)input輸入事件及使用防抖封裝函數(shù)處理方法的相關(guān)資料,最近有一個(gè)需求,需要我們實(shí)時(shí)監(jiān)聽(tīng)input輸入框中的內(nèi)容,從而帶來(lái)更好的用戶體驗(yàn),需要的朋友可以參考下2023-07-07