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