JavaScript 数组排序
数组排序方法
按字母顺序排序数组 sort()数组反转() 数组 toSorted() 数组 toReversed() 排序对象 另请参见基本方法搜索方法 迭代方法 |
数字排序数字排序随机排序 Math.min() Math.max() 自制 Min() 自制 Max() |
排序数组
The sort()
方法按字母顺序排序数组
反转数组
The reverse()
方法反转数组中的元素
通过组合 sort()
和 reverse()
,您可以按降序对数组进行排序
JavaScript 数组 toSorted() 方法
ES2023 添加了 toSorted()
方法作为一种安全的方式来对数组进行排序,而不会改变原始数组。
toSorted()
和 sort()
之间的区别在于,第一个方法创建一个新数组,保持原始数组不变,而最后一个方法会更改原始数组。
JavaScript 数组 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()
方法会调用比较函数(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 洗牌法,早在 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});
// 现在 points[0] 包含最低值
// 并且 points[points.length-1] 包含最高值
亲自尝试 »
降序排序
示例
const points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b - a});
// 现在 points[0] 包含最高值
// 并且 points[points.length-1] 包含最低值
亲自尝试 »
注意
如果您只想查找最高值(或最低值),那么对整个数组进行排序是一种非常低效的方法。
在数组上使用 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;
});
亲自尝试 »
稳定的数组 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