JS中sort方法详解

JS中sort方法详解

  sort() 方法用于对数组的元素进行排序,并返回排序后的数组。默认排序顺序是根据字符串Unicode码点(注意这里不是按ASCII编码排序,这里按Unicode编码排序要和平常两个字符串的<,>,<=,>=,一位位字符按ASCII编码排序区分开。)

语法:arrayObject.sort(func);参数func可选,规定排序顺序,必须是函数。

  注:如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照Unicode字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
eg:

1
2
3
4
5
var scores = [1, 10, 21, 2]; 
scores.sort();
// [1, 10, 2, 21]
// 注意10在2之前,
// 因为在 Unicode码点 指针顺序中"10""2"之前

  如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:

如果返回一个负数,则第一个参数应该排列在前面,即在排序后的数组中 a 应该出现在 b 之前。

如果 返回 0,表示a 等于 b,则a 和 b 的相对位置不变。(注意这里和排序算法的稳定性有关)

如果返回一个正数,则第二个参数应该排列在前面。

  所以,比较函数格式如下:

1
2
3
4
5
6
7
8
9
10
function compare(a, b) {
if (a < b ) { // 按某种排序标准进行比较, a 小于 b
return -1;
}
if (a > b ) {
return 1;
}
// a must be equal to b
return 0;
}

  要比较数字而非字符串,比较函数可以简单的以 a 减 b,如下的函数将会将数组升序排列:

1
2
3
function compareNumbers(a, b) {
return a - b;
}

  你可能还有疑问,就是为什么比较函数要放两个参数?我们可以拿V8引擎(Chrome浏览器的JS引擎)来理解。

  V8引擎使用C++开发,如果学过一点点数据结构课的话,肯定接触过排序这一块儿,什么快速排序、插入排序、冒泡排序的,然后大部分排序算法,步骤分解之后,最细节的操作都是两个数的相互比较,Chrome浏览器用的V8引擎就使用了快速排序。下面就贴一段当年学数据结构的时候快排的代码,V8的源码肯定不是这么简单,肯定是一种复杂的经过了各种优化(比如改善了稳定性,内存等)但基本的快排就是这样:左边右边一块儿往中间排,排出一个个有序的子段,然后再一个个子段中递归的排。

排序稳定性是指排序后数组中的相等值的相对位置没有改变,而不稳定性排序则会改变相等值的相对位置。

C++快速排序算法(这里是从小到大的正序算法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void quick_sort(int left,int right){
if(left>right){
return;
}
int pivot=data[left],low=left,high=right;
while(low<high){
while(low<high && data[high]>=pivot){
high--;
}
data[low]=data[high];
while(low<high && data[low]<=pivot){
low++;
}
data[high]=data[low];
}
data[low]=pivot;
quick_sort(left,low-1);
quick_sort(low+1,right);
}

  所以这样就清楚了,我们只要设置好了比较函数func(a,b)规定了每两个数排序的正逆序,就可以对整个数组进行快速排序,但要注意的是,因为快速排序是不稳定排序,所以sort方法也是不稳定的

  我们还可以令对象数组排序,这里是加强版排序,首先按last排序,然后按照first排序。

JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
var s=[
{first:"Tom",last:"cruse"},
{first:"Jack",last:"awddwa"},
{first:"Aommy",last:"rththr"},
{first:"Fuck",last:"ererg"},
{first:"Shit",last:"nbnb"},
{first:"Jessy",last:"awddwa"}
];
var by=function(name,minor){
return function(o,p){
var a,b;
if(typeof o==='object' && typeof p==='object' && o && p){
a=o[name];
b=p[name];
if(a===b){
//这里的minor(o,p)实际上是by('first')(o,p)
return typeof minor === 'function' ? minor(o,p) : 0;
}
if(typeof a=== typeof b){
return a<b?-1:1;
}
return typeof a < typeof b ? -1 : 1;
}else{
throw{
name: 'Error',
message: 'Expected an object when sorting by '+name
};
}
};
};
//因为by函数使用了闭包,这里的带两个参数的比较函数实际上是by(name)函数,即func(o,p)=by(name)(o,p)
//一个函数当参数的时候只写函数名即可,所以写成sort(by('last'))就行
s.sort(by("last",by("first")));
for(var i in s){
console.log(s[i].first+" "+s[i].last);
}

  更多关于sort()的内容,请见MDN文档

文章目录
  1. 1. JS中sort方法详解
    1. 1.0.1. 语法:arrayObject.sort(func);参数func可选,规定排序顺序,必须是函数。
    2. 1.0.2. 如果返回一个负数,则第一个参数应该排列在前面,即在排序后的数组中 a 应该出现在 b 之前。
    3. 1.0.3. 如果 返回 0,表示a 等于 b,则a 和 b 的相对位置不变。(注意这里和排序算法的稳定性有关)
    4. 1.0.4. 如果返回一个正数,则第二个参数应该排列在前面。
    5. 1.0.5. 排序稳定性是指排序后数组中的相等值的相对位置没有改变,而不稳定性排序则会改变相等值的相对位置。
,