JavaScript中sort方法的使用及原理详解

原生JS中提供了两个用来重排序的方法:reverse()和sort(),reverse()没什么好说的,就是直接使数组反转,例如下面的栗子:

    var arr = [1, 2, 3, 4, 5, -1, -10, 9, 0];
    arr.reverse();
    alert(arr);
    //0, 9, -10, -1, 5, 4, 3, 2, 1

运行结果就是数组的逆序,没什么好说的。

下面来详细说一下sort()这个方法:

sort方法可以直接调用,不传入任何参数,也可以传入一个比较函数作为参数,关于比较函数待会再解释,下面先说不传参的时候。

当不传入参数的时候,sort()方法会调用默认的排序的方式,即先调用每个数组项的toString()转型方法,然后按照字符串Unicode编码顺序来对字符串进行排序,例如下面的栗子:

    var arr = [1, 2, 3, 15, 22, 33];
    arr.sort();
    alert(arr);
    //1, 15, 2, 22, 3, 33

输出结果可能和想象中的不一样,但是这是按照这些数字在Unicode字符集中的顺序进行排序的。

那么怎么才能让他按照我们的想法对数组进行排序呢?没错,就是传入一个函数作为参数,来指明排序方式。(注意,参数必须是函数,不能是其他的)

这个函数可以像下面这样写:

    function cmp (value1, value2) {
        if (value1 < value2) {
            return 1;
        }
        else if (value1 > value2) {
            return -1;
        } else {
            return 0;
        }
    }

还是解释一下这个函数,如果value2大于value1,那么就会返回1,即true,那么就会执行交换,这样就会把较大的value2放在前面,则较小value1就放在后面。这样整体排下来就会是一个从大到小的排序。下面是一个实际应用的栗子:

    var arr = [1, 2, 3, 15, 22, 33, 44, 55, 0, -1, 22, 55];
    function cmp (value1, value2) {
        if (value1 < value2) {
            return 1;
        }
        else if (value1 > value2) {
            return -1;
        } else {
            return 0;
        }
    }
    arr.sort(cmp);
    alert(arr);

运行结果:


还有一种简化的cmp函数的书写方法:

    function cmp (a, b) {
        return b - a;
    }
这个函数和上面的函数作用是相同的,当b比较大的时候,就会返回一个大于等于1的数,即true,这样就会执行交换,总体结果也是一种降序排序,可以自己写代码试一下。

那么,现在实现了对数组中的数字进行排序,那么怎么实现根据数组对象中某个属性值进行排序呢?

这里就要用到JS函数的一个特点,就是用函数作为返回值,可以嵌套一层函数用来接收对象属性名,表示按照哪个属性进行排序:

<script type="text/javascript">
    var arr = [
        { name: 'guo', age: 20},
        { name: 'yu', age: 19},
        { name: 'liu', age: 15}
    ];

    function cmp (property) {
        return function (a, b){
            var value1 = a[property];
            var value2 = b[property];

            return value1 - value2;
        }
    }
    arr.sort(cmp('age'));
    for (var i=0; i<3; i++) {
        alert(arr[i].name);
    }
    //liu, yu, guo
</script>

有些人可能现在的cmp函数不太理解,那么可以调试一下这段代码看看究竟发生了什么:


可以看到,cmp函数中的property只是起到了标识的作用,而实际上arr中的数据是传递给了内部的function,然后由内部的function的参数来根据property来取得需要进行比较的值进行比较。

那么sort函数内部是按照什么排序方法进行排序的呢?看一下js实现sort方法的底层代码就知道了:


代码链接:chromium v8引擎array.js   第710行开始。

猜你喜欢

转载自blog.csdn.net/thelostlamb/article/details/79621208