JS sort的原理
JavaScript中的sort方法用于对数组元素进行排序。它采用一种称为“原地排序”的方法,这意味着它会修改原始数组,而不会创建新的排序数组。
sort方法的排序原理基于一种称为比较函数的概念。比较函数是一个接受两个参数的函数,它根据这两个参数的关系来确定它们在排序后的位置。比较函数应该返回一个负数、零或正数,分别表示第一个参数小于、等于或大于第二个参数。
排序方法的大致原理如下:
sort方法首先会将数组元素按照默认的字符串顺序进行排序。这意味着它会将数组中的元素都视为字符串,并按照Unicode字符编码的顺序进行比较。
如果你提供了一个比较函数作为sort方法的参数,那么它会使用该函数来决定元素的排序顺序。比较函数会在每一对元素上调用,根据比较函数的返回值来确定它们的相对位置。
下面是一个示例,展示了如何使用sort方法对数字数组进行升序排序:
const numbers = [5, 2, 9, 1, 5];
numbers.sort(function(a, b) {
return a - b; // 升序排序
});
console.log(numbers); // 输出:[1, 2, 5, 5, 9]
在这个示例中,比较函数 function(a, b) { return a - b; } 返回负数、零或正数,以便排序函数知道如何排列元素。
需要注意的是,sort方法默认是基于字符串比较的,因此如果你直接使用它来排序数组,可能会得到意想不到的结果,特别是在处理数字时。所以,通常需要提供一个自定义的比较函数,以确保排序按照你的预期进行。如果需要降序排序,只需在比较函数中交换 a 和 b 的位置即可。
遇到的问题
.sort(
(p1, p2) => {
if (p1.status === targetstatus
&& p2.status !== targetstatus) {
return -1;
}
if (p1.status === targetstatus
&& p2.status === targetstatus) {
if (!isReady(p1) && isReady(p2)) {
return -1;
}
}
return p2.duration- p1.duration;
}
以上排序代码发现,对于很多情况下的p2 isNotReady的case,仍然排在了后面。
问题原因
对于一串数组,两个元素的比较只会比较一次,那就意味着p1, p2的元素的进场比较顺序不确定。 所以为了考虑全部的场景,应该代码改为
.sort(
(p1, p2) => {
if (p1.status === targetstatus
&& p2.status !== targetstatus) {
return -1;
}
if (p1.status !== targetstatus
&& p2.status === targetstatus) {
return 1;
}
if (p1.status === targetstatus
&& p2.status === targetstatus) {
if (!isReady(p1) && isReady(p2)) {
return -1;
}
if (isReady(p1) && !isReady(p2)) {
return 1;
}
}
return p2.duration- p1.duration;
}