array.sort(compare)
,现在书上写道如果compare
函数返回a-b
(数组的两个索引值),则排序是基于结果是否大于0、小于0或等于0来完成的。但是,它究竟是如何工作的呢?我无法理解。array.sort(compare)
,现在书上写道如果compare
函数返回a-b
(数组的两个索引值),则排序是基于结果是否大于0、小于0或等于0来完成的。但是,它究竟是如何工作的呢?我无法理解。function compare(a,b) {
return a - b;
}
如果a大于b,简单地从a中减去b将始终返回大于零的值;如果它们相等,则返回0;如果a小于b,则返回小于零的值。 因此,它符合比较函数的要求。
现在假设这是我们要排序的数字列表:
var numbers = [1,5,3.14];
当你调用 numbers.sort(compare)
时,内部实际上会执行:
compare(1,5); // Returns -4, a is less than b
compare(1,3.14); // Return -2.14, a is less than b
compare(5,3.14); // returns 1.86, a is greater than b
如果你曾经进行过手动排序或字母排序,你可能已经做了完全相同的事情,只是没有意识到。即使您有数十个或数百个要比较的项,您也始终只比较两个数字(或作者姓氏等)。 再次浏览三个数字的短列表,您将从比较前两个数字开始:
默认情况下,数组的sort()
方法按字母升序排序。如果您想以其他方式对数组进行排序,因为数组包含数字或对象,则可以将一个函数传递给sort()
。
您传递的函数接受两个参数,通常称为a和b,并返回: 如果第一个参数应该在第二个参数之前排序(a<b),则返回负数 如果参数相等(a==b),则返回0 如果第一个参数应该在第二个参数之后排序(a>b),则返回正数
现在,这里是关键点:您作为参数传递给sort()
的函数将被sort()
重复调用,因为它处理整个数组。 sort()
不知道也不关心数组中物品的数据类型:每次需要知道“项目A是否在项目B之前?”时,它只会调用您的函数。 您无需担心sort()
内部使用了什么类型的排序算法,实际上,一个浏览器可能会使用与另一个不同的算法,但这没关系,因为您只需提供一种比较数组中任意两个项的方法即可。
对于数字,您的函数可以具有if / else if / else
结构来决定返回什么结果,但是简单地返回(a-b)就可以为您实现这一点,因为减法的结果将为-ve,0或+ve,并正确地按升序放置数字。返回(b-a)会使它们降序。
var sortedArray = myArray.sort(function(a,b){
return (a-b);
});
如果您有一个对象数组并且想要按照某些特定属性对对象进行排序,也可以这样做。 假设,例如,对象的格式如下:
{ id : 1,
name : "Fred",
address : "12 Smith St",
phone : "0262626262" }
那么,您可以按照以下方式通过它们的“id”属性对这些对象的数组进行排序:
var sortedArray = myArray.sort(function(a,b){
return (a.id - b.id);
});
或者你可以通过以下方式按照“名称”属性(按字母顺序)对这些对象的数组进行排序:
var sortedArray = myArray.sort(function(a,b){
if (a.name < b.name)
return -1;
else if (a.name == b.name)
return 0;
else
return 1;
});
请注意,在我的最终示例中,我已经放置了我之前提到的完整的if / else if / else结构。b - a
或a - b
。结果是一样的,对吗?在这种情况下,-1和1没有什么特别的区别或显著差异吗? - CodeFinityfunction compare(a, b) {
// make some operations to calculate these variables as true or false
// weNeedToMoveFirstParameterInPositiveDirection
// weDoNotNeedToMove
// weNeedToMoveFirstParameterInNegativeDirection
// just think about numerical axis <------(-1)---(0)---(1)------>
if (weNeedToMoveFirstParameterInPositiveDirection) return 1;
if (weDoNotNeedToMove) return 0;
if (weNeedToMoveFirstParameterInNegativeDirection) return -1;
}
如果数组是字符串类型的,排序方法会把数字作为字符串处理,这时候不需要比较函数。 但是如果数组是数字类型的,你需要使用比较函数来改变排序方法的行为。
例1:字符串类型的数组
var animals = ["Horse", "Cat", "Tiger", "Lion"];
animals.sort();
示例2:数字
var marks = [70, 90, 60, 80 ];
marks.sort(function(a, b){return a > b}); //ascending , a < b descending .
目前可以使用 Uint32Array 创建数组。
[https://istack.dev59.com/qBgvm.webp]
但是,它存在一些困难。例如,您无法向数组添加新值。简单地说,您无法修改数组的长度。
我认为可能是这样的(好吧,我不确定):
假设函数compare(a,b)
是比较函数。
它返回c
。
假设我们要对数组N
中的条目进行排序,以获得排序结果数组M
。
我不知道确切的排序算法,而且如果c
既不是(a-b)
也不是(b-a)
(例如,如果c
是"b-2"
、"a+b"
或其他一些表达式),不同的浏览器甚至会返回不同的结果。
但根据ECMA-262
,排序结果应该是这样的:
a,b可以是任意两个索引。
这意味着我们实际上向比较函数传递了一个有序对。
例如:(0,1),(1,4),甚至是(2,0),(2,1)
。
ECMAScript语言规范指出,结果应具有以下属性:
(a,b)
是传递给比较函数的有序对。
c
小于零,则必须满足 M(a)< M(b)
。而规范并没有说明如果 c 等于零或大于零会发生什么。
我不确定这是否正确。
至少这可以很容易地解释为什么当 c
是 "a-b"
时,条目按数字和升序排序,而当 c
是 "b-a"
时,条目按相反顺序排序。
浏览器的 js 引擎是否真的严格按照 `ECMA-262` 设计,还是我完全错了?
参考:
[1,4,3,5]
,[1, 3,...]
,按照你希望的排序方式。这可能是棘手的一部分:
现在根据这个模型定义compareFn。
(不使用三元运算符)
const myArray = [1,4,3,5]
function compareFn(a,b){
if(b < a) return 1
return -1
}
console.log(myArray.sort(compareFn))
const myArray = [1,4,3,5]
function compareFn(a,b){
return b > a ? 1 : -1
}
console.log(myArray.sort(compareFn))