JavaScript原生Array.sort
方法也能輕鬆搞定對像數組排序!本文將演示如何使用Array.sort
方法對包含字符串、數字和日期的對像數組進行排序,並提供處理大小寫敏感性、數組複製以及常用庫的實用技巧。
核心要點
Array.sort
方法可用於排序對像數組,利用比較函數定義字符串、數字、日期和其他屬性的排序邏輯。 Array.sort
方法會修改其排序的原始數組。為避免這種情況,可以使用Array.slice
方法或擴展運算符創建一個新的數組實例並進行排序。 基礎數組排序(以及為什麼它不起作用)
默認情況下,JavaScript Array.sort
方法會將需要排序的數組中的每個元素轉換為字符串,並按Unicode代碼點順序進行比較。
const foo = [9, 1, 4, 'zebroid', 'afterdeck']; foo.sort(); // 返回 [ 1, 4, 9, 'afterdeck', 'zebroid' ] const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }]; bar.sort(); // 返回 [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]
你可能會好奇為什麼32在5之前?看似不合理,對吧?其實不然。這是因為數組中的每個元素首先被轉換為字符串,而“32”在Unicode順序中位於“5”之前。
僅使用Array.sort
無法有效地對對像數組進行排序。幸運的是,sort
方法接受一個可選的compareFunction
參數,我們可以用它來排序對像數組。
如何在JavaScript中排序對像數組
要排序對像數組,請使用帶有比較函數的sort()
方法。比較函數應用規則,根據我們自定義的邏輯對數組進行排序。它們允許我們根據字符串、整數、日期或任何其他自定義屬性對對像數組進行排序。我們稍後將在本文中介紹比較函數的工作原理。
在本演示中,我們將使用一個歌手數組,並按其樂隊名稱的字母順序對其進行排序:
const singers = [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, ];
以下比較函數比較每個樂隊的(大寫)名稱:
function compare(a, b) { // 使用 toUpperCase() 忽略字符大小写 const bandA = a.band.toUpperCase(); const bandB = b.band.toUpperCase(); let comparison = 0; if (bandA > bandB) { comparison = 1; } else if (bandA < bandB) { comparison = -1; } return comparison; } singers.sort(compare); /* 返回 [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 } ] */
要反轉排序順序,您可以反轉比較函數的返回值:
const foo = [9, 1, 4, 'zebroid', 'afterdeck']; foo.sort(); // 返回 [ 1, 4, 9, 'afterdeck', 'zebroid' ] const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }]; bar.sort(); // 返回 [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]
比較函數返回一個數字,該數字用於通過比較其兩個輸入(a和b)來確定排序順序。簡單來說,如果整數小於0,則a出現在b之前;如果大於0,則b出現在a之前;如果正好為0,則保持原始順序。但是你如何確定這個數字取決於你。
讓我們來看一個簡單的數字數組示例:
const singers = [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, ];
我們可以對其進行一些重構,因為將b減去a也會給我們返回值。此比較函數將數字數組從小到大排序:
function compare(a, b) { // 使用 toUpperCase() 忽略字符大小写 const bandA = a.band.toUpperCase(); const bandB = b.band.toUpperCase(); let comparison = 0; if (bandA > bandB) { comparison = 1; } else if (bandA < bandB) { comparison = -1; } return comparison; } singers.sort(compare); /* 返回 [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 } ] */
它也可以表示為箭頭函數,而無需在其他地方定義比較函數:
function compare(a, b) { // ... // 通过乘以 -1 反转返回值 return comparison * -1; }
如果你不熟悉箭頭函數,可以在這裡閱讀更多關於它們的信息:JavaScript中的箭頭函數。
如你所見,比較函數可以用多種方式編寫,sort()
方法將按指示執行。
讓我們完成我們之前的示例,使其更具動態性。讓我們創建一個排序函數,你可以使用它來排序對像數組,其值是字符串或數字。此函數有兩個參數——我們要排序的鍵以及結果的順序(即升序或降序):
const nums = [79, 48, 12, 4]; function compare(a, b) { if (a > b) return 1; if (b > a) return -1; return 0; } nums.sort(compare); // => 4, 12, 48, 79
以下是如何使用它:
function compareNums(a, b) { return a - b; } nums.sort(compareNums)
在上面的代碼中,hasOwnProperty
方法用於檢查指定的屬性是否在每個對像上定義,並且沒有通過原型鏈繼承。如果它沒有在兩個對像上定義,則函數返回0,這會導致排序順序保持不變(即對象相對於彼此保持不變)。
typeof
運算符還用於檢查屬性值的類型。這允許函數確定對數組進行排序的正確方法。例如,如果指定屬性的值是字符串,則使用toUpperCase
方法將所有字符轉換為大寫,因此在排序時會忽略字符大小寫。
你可以調整上述函數以適應其他數據類型,以及你的腳本可能需要的任何其他需求。
流行的數組排序庫
你可能沒有時間或耐心在原生JavaScript中創建你自己的排序函數。時間就是金錢,代碼需要時間。幸運的是,有各種各樣的庫可以滿足你所有的數組排序需求。以下是一些包含排序函數的輔助庫的簡短列表……沒有特別的順序;)
快速提示:按日期排序對像數組
要按日期字符串對對像數組進行排序,你只需提供一個比較函數,該函數首先解析日期字符串,然後將它們相互減去:
nums.sort((a, b) => a - b);
快速提示:不修改數組進行排序
與許多其他JavaScript數組函數不同,Array.sort
是會改變(修改)其排序的數組而不是返回新數組的方法之一。為避免這種情況,你可以創建一個要排序的數組的新實例並對其進行修改。這可以使用數組方法或擴展語法來創建數組副本。
const foo = [9, 1, 4, 'zebroid', 'afterdeck']; foo.sort(); // 返回 [ 1, 4, 9, 'afterdeck', 'zebroid' ] const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }]; bar.sort(); // 返回 [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]
使用Array.slice
創建數組副本:
const singers = [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, ];
或者,你可以使用擴展運算符獲得相同的效果:
function compare(a, b) { // 使用 toUpperCase() 忽略字符大小写 const bandA = a.band.toUpperCase(); const bandB = b.band.toUpperCase(); let comparison = 0; if (bandA > bandB) { comparison = 1; } else if (bandA < bandB) { comparison = -1; } return comparison; } singers.sort(compare); /* 返回 [ { name: 'Steven Tyler', band: 'Aerosmith', born: 1948 }, { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 }, { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 }, { name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 } ] */
在這兩種情況下,輸出都是相同的,並且可以在排序任何對像數組之前使用。
function compare(a, b) { // ... // 通过乘以 -1 反转返回值 return comparison * -1; }
快速提示:不區分大小寫的方式按字符串排序數組
在我們之前的示例中,我們希望排序對像數組,其值是字符串或數字。但是,如果你知道你只會處理其值為字符串的對象,則可以使用JavaScript的localeCompare
方法來整理代碼。
此方法返回一個數字,該數字指示字符串在排序順序中是位於給定字符串之前、之後還是與之相同。它允許對數組進行不區分大小寫的排序:
const nums = [79, 48, 12, 4]; function compare(a, b) { if (a > b) return 1; if (b > a) return -1; return 0; } nums.sort(compare); // => 4, 12, 48, 79
就我們的compareValues
函數而言,這意味著我們可以這樣寫:
function compareNums(a, b) { return a - b; } nums.sort(compareNums)
你可以在MDN上閱讀更多關於localeCompare
的信息。
結論
就是這樣——關於使用原生JavaScript排序對像數組的簡短介紹。儘管許多庫提供了這種動態排序功能,但正如所示,自己實現此功能並不難。此外,了解幕後發生的事情也很有益。
為了構建對原生JavaScript基礎的更全面的理解,我們推薦JavaScript:從新手到忍者。從頭開始學習JavaScript,包括ES6,並通過一系列項目來實踐你的新知識。
關於如何在JavaScript中排序對像數組的常見問題解答
是的。 JavaScript提供了內置方法來幫助排序數組元素。
你可以使用Array.prototype.sort()
方法並提供自定義比較函數來對JavaScript中的對像數組進行排序。比較函數應該比較每個對象的相關屬性。
你可以通過向比較函數提供鍵來動態地根據不同的鍵對對像數組進行排序。這允許你按各種屬性進行排序。要按JavaScript中特定鍵(屬性)對對像數組進行排序,你可以使用Array.prototype.sort()
方法以及自定義比較函數,該函數比較每個對象的所需鍵的值。
要根據運行時確定的鍵(屬性)動態地對JavaScript中的對像數組進行排序,你可以創建一個函數,該函數接受數組和鍵作為參數。然後,此函數可以使用Array.prototype.sort()
方法以及自定義比較函數來訪問用於排序的動態提供的鍵。
是否有任何庫可以簡化對像數組的排序?是的,像Lodash和Underscore.js這樣的庫提供了用於排序對像數組的實用程序函數,並具有附加功能和便利性。但是,JavaScript的內置sort()
方法通常足以滿足基本的排序需求。
按對象鍵排序是否區分大小寫?是的,默認情況下,按對象鍵排序區分大小寫。你可以使用localeCompare()
方法執行不區分大小寫的排序。
以上是用sort()方法在JavaScript中對對象進行排序的詳細內容。更多資訊請關注PHP中文網其他相關文章!