JavaScript 排序陣列
陣列排序方法
字母排序Array sort()Array reverse() Array toSorted() Array toReversed() 排序物件 另請參閱基本方法搜尋方法 迭代方法 |
數字排序數字排序隨機排序 Math.min() Math.max() 自制 Min() 自制 Max() |
排序陣列
sort()
方法按字母順序對陣列進行排序
反轉陣列
reverse()
方法反轉陣列中的元素
透過組合使用 sort()
和 reverse()
,您可以按降序對陣列進行排序
JavaScript Array toSorted() 方法
ES2023 添加了 toSorted()
方法,作為一種安全的方式來對陣列進行排序,而不會改變原始陣列。
toSorted()
和 sort()
之間的區別在於,第一個方法建立一個新陣列,保持原始陣列不變,而最後一個方法會改變原始陣列。
JavaScript Array toReversed() 方法
ES2023 添加了 toReversed()
方法,作為一種安全的方式來反轉陣列,而不會改變原始陣列。
toReversed()
和 reverse()
之間的區別在於,第一個方法建立一個新陣列,保持原始陣列不變,而最後一個方法會改變原始陣列。
數字排序
預設情況下,sort()
函式將值作為字串排序。
這對於字串來說效果很好(“Apple”排在“Banana”之前)。
如果數字被當作字串排序,“25”比“100”大,因為“2”比“1”大。
因此,當排序數字時,sort()
方法將產生不正確的結果。
您可以透過提供一個比較函式來修復此問題
使用相同的技巧對陣列進行降序排序
比較函式
比較函式的目的是定義一個替代的排序順序。
比較函式應根據引數返回負值、零或正值
function(a, b){return a - b}
當 sort()
函式比較兩個值時,它會將這些值傳遞給比較函式,並根據返回的(負值、零、正值)值對這些值進行排序。
如果結果為負,則 a
在 b
之前排序。
如果結果為正,則 b
在 a
之前排序。
如果結果為 0,則兩個值的排序順序不會發生變化。
示例
比較函式會一次比較陣列中的所有值,每次比較兩個值 (a, b)
。
當比較 40 和 100 時,sort()
方法會呼叫 compare function(40, 100)。
該函式計算 40 - 100 (a - b)
,由於結果為負值 (-60),因此排序函式會將 40 排序為低於 100 的值。
您可以使用此程式碼片段進行數字和字母排序實驗
<button onclick="myFunction1()">字母排序</button>
<button onclick="myFunction2()">數字排序</button>
<p id="demo"></p>
<script>
const points = [40, 100, 1, 5, 25, 10];
document.getElementById("demo").innerHTML = points;
function myFunction1() {
points.sort();
document.getElementById("demo").innerHTML = points;
}
function myFunction2() {
points.sort(function(a, b){return a - b});
document.getElementById("demo").innerHTML = points;
}
</script>
自己動手試一試 »
隨機排序陣列
使用排序函式,如上所述,您可以隨機排序數字陣列
示例
const points = [40, 100, 1, 5, 25, 10];
points.sort(function(){return 0.5 - Math.random()});
Fisher Yates 方法
上面示例中的 points.sort() 方法不準確。它會偏向某些數字而不是其他數字。
最流行的正確方法稱為 Fisher Yates shuffle,早在 1938 年就在資料科學中引入了!
在 JavaScript 中,該方法可以轉換為
示例
const points = [40, 100, 1, 5, 25, 10];
for (let i = points.length -1; i > 0; i--) {
let j = Math.floor(Math.random() * (i+1));
let k = points[i];
points[i] = points[j];
points[j] = k;
}
查詢陣列中的最小值(或最大值)
沒有內建函式用於查詢陣列中的最大值或最小值。
要查詢最小值或最大值,您有 3 個選項
- 對陣列進行排序並讀取第一個或最後一個元素
- 使用 Math.min() 或 Math.max()
- 編寫自制函式
使用 sort() 查詢最小值或最大值
對陣列進行排序後,您可以使用索引來獲取最大值和最小值。
升序排序
示例
const points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});
// now points[0] contains the lowest value
// and points[points.length-1] contains the highest value
自己動手試一試 »
降序排序
示例
const points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b - a});
// now points[0] contains the highest value
// and points[points.length-1] contains the lowest value
自己動手試一試 »
注意
如果只想查詢最大值(或最小值),對整個陣列進行排序是非常低效的方法。
在陣列上使用 Math.min()
您可以使用 Math.min.apply
來查詢陣列中的最小值
Math.min.apply(null, [1, 2, 3])
等同於 Math.min(1, 2, 3)
。
在陣列上使用 Math.max()
您可以使用 Math.max.apply
來查詢陣列中的最大值
Math.max.apply(null, [1, 2, 3])
等同於 Math.max(1, 2, 3)
。
JavaScript 陣列最小值方法
JavaScript 陣列沒有內建函式用於查詢最小值。
查詢最小數字的最快程式碼是使用自制方法。
此函式遍歷陣列,將每個值與找到的最小值進行比較
示例(查詢最小值)
function myArrayMin(arr) {
let len = arr.length;
let min = Infinity;
while (len--) {
if (arr[len] < min) {
min = arr[len];
}
}
return min;
}
JavaScript 陣列最大值方法
JavaScript 陣列沒有內建函式用於查詢最大值。
查詢最大數字的最快程式碼是使用自制方法。
此函式遍歷陣列,將每個值與找到的最大值進行比較
示例(查詢最大值)
function myArrayMax(arr) {
let len = arr.length;
let max = -Infinity;
while (len--) {
if (arr[len] > max) {
max = arr[len];
}
}
return max;
}
排序物件陣列
JavaScript 陣列通常包含物件
示例
const cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}
];
即使物件屬性的資料型別不同,也可以使用 sort()
方法對陣列進行排序。
解決方案是編寫一個比較函式來比較屬性值
比較字串屬性要複雜一些
示例
cars.sort(function(a, b){
let x = a.type.toLowerCase();
let y = b.type.toLowerCase();
if (x < y) {return -1;}
if (x > y) {return 1;}
return 0;
});
自己動手試一試 »
穩定的 Array sort()
ES2019修改了 Array sort()
方法。
在 2019 年之前,該規範允許使用 QuickSort 等不穩定排序演算法。
在 ES2019 之後,瀏覽器必須使用穩定的排序演算法
當根據值對元素進行排序時,具有相同值的元素必須保持其相對位置。
示例
const myArr = [
{name:"X00",price:100 },
{name:"X01",price:100 },
{name:"X02",price:100 },
{name:"X03",price:100 },
{name:"X04",price:110 },
{name:"X05",price:110 },
{name:"X06",price:110 },
{name:"X07",price:110 }
];
自己動手試一試 »
在上面的示例中,當按價格排序時,不允許出現以下名稱相對位置與其他元素不同的結果
X01 100
X03 100
X00 100
X03 100
X05 110
X04 110
X06 110
X07 110