如何在JavaScript中使用sortingfunction以及比较function

正如已经问到的那样:在JavaScript中如何使用sorting函数以及compare函数? 如果我有一个数组,现在我做了array.sort(compare)现在写在书中,如果compare函数返回ab (数组的两个索引),那么它的工作原理是,结果是否大于0,小于0或等于0.但是,它究竟是如何工作的呢? 我无法解决这个问题。

“比较”函数必须有两个参数,通常称为ab 。 然后,根据这些值ab ,使比较函数返回0,大于0或小于0。

  1. 如果a大于b,则返回大于0
  2. 如果a等于b,则返回0
  3. 如果a小于b,则返回小于0

有了这三个返回值,只有两个参数,可以编写一个比较函数,它可以对任何types的input数据types或复杂的数据结构进行sorting。

然后,当你调用sort()时,用你自定义的比较函数,比较函数将在你的待分类列表中的对上调用,以确定正确的sorting。

让我们通过一个简单的例子…假设你只是sorting一些数字,所以我们有一个非常简单的比较函数:

 function compare(a,b) { return a - b; } 

如果a大于b,简单地从a中减去b将总是返回大于零,如果它们相等,则返回0;如果a小于b,则返回小于零。 所以它符合比较function的要求。

现在让我们假设这是我们要sorting的数字列表:

 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 

如果你曾经做过手工sorting或字母sorting,你完成了完全相同的事情,可能没有意识到。 即使你可能有几十或几百个项目要比较,你一直只比较两个数字(或作者的姓氏,或其他)。 再次浏览一下三个数字,你会开始比较前两个数字:

  1. 1大于还是小于5? 不到,所以把这两个数字放在我们的列表中:1,5
  2. 3.14大于还是小于1? 大于,所以它在新列表中的1之后
  3. 我们的新名单中3.14大于还是小于5? 不到,所以它在5之前。我们的新名单现在是[1,3.14,5]

因为您可以提供自己的compare()函数,所以可以对任意复杂的数据进行sorting,而不仅仅是数字。

默认情况下,数组sort()方法按字母顺序升序sorting。 如果你想以其他顺序sorting,因为你的数组包含数字或对象,那么你可以将一个函数传递给sort()

传入的函数有两个参数,通常称为a和b,并返回:如果第一个参数应该在第二个参数之前sorting,则返回负数(a <b)如果参数相等则为0(a == b)为正如果第一个参数应该排在第二个之后(a> b)

现在, 这里是关键的一点 :作为sort()parameter passing的函数在处理整个数组时会被sort()重复调用。 sort()不知道或关心数组中的事物的数据types:每次需要知道“项目A是否在项目B之前? 它只是调用你的function。 您不必担心sort()内部使用什么types的sortingalgorithm,实际上一个浏览器可能使用另一个algorithm,但这没关系,因为您只需提供一种方法来比较任何两个项目从你的arrays。

你的函数可以有一个if / else if / else结构来决定返回的结果,但是对于你简单地返回(ab)的数字,你会得到这个结果,因为减法的结果是-ve,0或者+ ve并且正确的数字按升序排列。 返回(ba)会使他们下降:

  var sortedArray = myArray.sort(function(a,b){ return (ab); }); 

如果你有一个对象数组,并想对某些特定的属性或属性进行sorting,你也可以这样做。 假设,例如,这种格式的对象:

 { id : 1, name : "Fred", address : "12 Smith St", phone : "0262626262" } 

然后你可以通过它们的'id'属性来sorting这些对象的数组,如下所示:

 var sortedArray = myArray.sort(function(a,b){ return (a.id - b.id); }); 

或者,您可以按照如下所示按“name”属性(按字母顺序排列)对这些对象进行sorting:

 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结构。

对于用多个属性sorting对象的示例,您可以进一步扩展以包含次要sorting,也就是(在我的示例中)如果名称属性相同,则可以返回比较(例如,电话属性)。

此方法使用Array.sort(compareFunction sortOptions)的顺序的语法和参数,其参数定义如下:

compareFunction – 用于确定数组元素sorting顺序的比较函数。 该参数是可选的。 比较函数应该用来比较这两个参数。 给定元素的A和B,compareFunction的结果可以为负值,即0或正值:

如果返回值是负值,则意味着A在sorting的序列中出现在B之前。 如果返回值为0,则A和B具有相同的sorting顺序。 如果返回值是正数,则意味着A在sorting后的序列中出现在B之后。

单独的sorting方法将数字视为string,所以如果string数组不需要比较函数。 但是如果数组数组需要使用比较函数来改变sorting方法的构build行为。

ex1:string

 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 . 

我想这可能是这样的(当然,我不确定)。

假设函数compare(a,b)是比较函数。 它返回c 。 假设我们要对数组N的条目进行sorting,以得到sorting结果数组M

我不知道确切的sortingalgorithm,如果c既不是(ab)也不是(ba) (如果c"b-2""a+b"或其他expression式),那么不同的浏览器甚至返回不同的结果。 。

但根据ECMA-262 ,sorting结果应该是这样的:

a,b可以是任何两个索引。 这意味着我们实际上将一个有序对传递给比较函数。 eg: (0,1),(1,4), or even (2,0) , (2,1)

ECMAScript语言规范说结果应该有这个属性: (a,b)是一个传递给比较函数的有序对。

  • 如果c (函数返回的)小于零,则必须满足M(a)< M(b)

并且规范没有说明如果c是零或大于零会发生什么。

我不确定这是否正确。 至less这可以很容易地解释为什么当c"ab" ,条目被sorting为数字和升序,为什么当c"ba" ,条目被sorting到相反。

浏览器的js引擎是不是严格按照ECMA-262devise的,还是我完全错了?

参考:

第五版ECMA-262(检查第129-130页)