js数组排序

1、普通数组排序  

  js中用方法sort()为数组排序。sort()方法有一个可选参数,是用来肯定元素顺序的函数。若是这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序。如:数组

var arr = ["a", "b", "A", "B"];
arr.sort();
console.log(arr);//["A", "B", "a", "b"]

由于字母A、B的ASCII值分别为6五、66,而a、b的值分别为9七、98,因此上面输出的结果是 ["A", "B", "a", "b"] 。服务器

  若是数组元素是数字呢,结果会是怎样?函数

var arr = [15, 8, 25, 3];
arr.sort();
console.log(arr);//[15, 25, 3, 8]

结果是 [15, 25, 3, 8] 。其实,sort方法会调用每一个数组项的toString()方法,获得字符串,而后再对获得的字符串进行排序。虽然数值15比3大,但在进行字符串比较时"15"则排在"3"前面。显然,这种结果不是咱们想要的,这时,sort()方法的参数就起到了做用,咱们把这个参数叫作比较函数。spa

  比较函数接收两个参数,若是第一个参数应该位于第二个以前则返回一个负数,若是两个参数相等则返回0,若是第一个参数应该位于第二个以后则返回一个正数。例子:code

复制代码
var arr = [23, 9, 4, 78, 3];
var compare = function (x, y) {//比较函数
    if (x < y) {
        return -1;
    } else if (x > y) {
        return 1;
    } else {
        return 0;
    }
}
console.log(arr.sort(compare));        
复制代码

结果为 [3, 4, 9, 23, 78] ,返回了咱们想要的结果。若是要按降序排序,比较函数写成这样便可:对象

复制代码
var compare = function (x, y) {
    if (x < y) {
        return 1;
    } else if (x > y) {
        return -1;
    } else {
        return 0;
    }
}
复制代码

  咱们并不能用比较函数比较一个不能转化为数字的字符串与数字的顺序:blog

var arr = ["b", 5];
console.log(arr.sort(compare))

结果是 ["b", 5] 。由于比较函数在比较时,会把先把字符串转化为数字,而后再比较,字符串b不能转化为数字,因此就不能比较大小。然而,当不用比较函数时,会比较ASCII值,因此结果是 [5, "b"] 。排序

2、数组对象排序

  若是数组项是对象,咱们须要根据数组项的某个属性对数组进行排序,要怎么办呢?其实和前面的比较函数也差很少:字符串

复制代码
var arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}];
var compare = function (obj1, obj2) {
    var val1 = obj1.name;
    var val2 = obj2.name;
    if (val1 < val2) {
        return -1;
    } else if (val1 > val2) {
        return 1;
    } else {
        return 0;
    }            
} 
console.log(arr.sort(compare));
复制代码

  输出结果为 [Object { name="wlz", age=25}, Object { name="zlw", age=24}] ,能够看到数组已经按照 name 属性进行了排序。咱们能够对上面的比较函数再改造一下:it

复制代码
var compare = function (prop) {
    return function (obj1, obj2) {
        var val1 = obj1[prop];
        var val2 = obj2[prop];if (val1 < val2) {
            return -1;
        } else if (val1 > val2) {
            return 1;
        } else {
            return 0;
        }            
    } 
}
复制代码

若是想按照 age 进行排序, arr.sort(compare("age")) 便可。

  可是对age属性进行排序时须要注意了,若是age属性的值是数字,那么排序结果会是咱们想要的。但不少时候咱们从服务器传回来的数据中,属性值一般是字符串。如今我把上面的数组改成:

var arr = [{name: "zlw", age: "24"}, {name: "wlz", age: "5"}];

能够看到,我把 age 属性由数字改成了字符串,第二个数组项的 age 值改成了 "5" 。再次调用 arr.sort(compare("age")) 后,结果为:

[Object { name="zlw", age="24"}, Object { name="wlz", age="5"}]

咱们的指望是5排在25前面,可是结果不是。这是由于当两个数字字符串比较大小时,会比较它们的ASCII值大小,比较规则是:从第一个字符开始,顺次向后直到出现不一样的字符为止,而后以第一个不一样的字符的ASCII值肯定大小。因此"24"与"5"比较大小时,先比较”2“与"5"的ASCII值,显然”2“的ASCII值比"5"小,即肯定排序顺序。

  如今,咱们须要对比较函数再作一些修改:

复制代码
var compare = function (prop) {
    return function (obj1, obj2) {
        var val1 = obj1[prop];
        var val2 = obj2[prop];
        if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
            val1 = Number(val1);
            val2 = Number(val2);
        }
        if (val1 < val2) {
            return -1;
        } else if (val1 > val2) {
            return 1;
        } else {
            return 0;
        }            
    } 
}
复制代码

在比较函数中,先把比较属性值转化为数字 Number(val1) 再经过 !isNaN(Number(val1)) 判断转化后的值是否是数字(有多是NaN),转化后的值若是是数字,则比较转换后的值,这样就能够获得咱们想要的结果了, 调用  arr.sort(compare("age")) 获得:

[Object { name="wlz", age="5"}, Object { name="zlw", age="24"}]

能够看到,确实是按正确的方式排序了。