Skip to content

排序方法

数组中已经存在两个可以直接用来重排序的方法:reverse()sort()
reverse()方法会反转数组项的顺序。

试一试

const array = [1, 2, 3, 4, 5, 6]
result:

reverse

reverse()方法的作用相当直观明了,但不够灵活,因此才有了sort()方法` 。

在默认情况下,sort()方法按升序排列数组项,即最小的值位于最前面,最大的值排在最后面。为了实现排序,sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串,以确定如何排序。即使数组中的每一项都是数值,sort()方法比较的也是字符串。

示例代码

js
const array = [0, 1, 5, 10, 15];
array.sort();
console.log(array); // [0, 1, 10, 15, 5]

这样得到的结果并不符合数值排序的预期(5 应该小于 10)。因此sort()方法可以接受一个比较函数作为参数,以便指定哪个值位于哪个值的前面。
比较函数接受两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。下面是使用简单比较函数的一 个例子:

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

这个比较函数可以适用于大多数数据类型,可以把它当作参数传给 sort()方法,如下所示:

js
let values = [0, 1, 5, 10, 15];
values.sort(compare);
console.log(values); // 0,1,5,10,15

在给 sort()方法传入比较函数后,数组中的数值在排序后保持了正确的顺序。当然,比较函数也 可以产生降序效果,只要把返回值交换一下即可:

js
function compare(value1, value2) {
  if (value1 < value2) {
    return 1;
  } else if (value1 > value2) {
    return -1;
  } else {
    return 0;
  }
}
let values = [0, 1, 5, 10, 15];
values.sort(compare);
console.log(values); // 15,10,5,1,0

此外,这个比较函数还可简写为一个箭头函数:

js
let values = [0, 1, 5, 10, 15];
values.sort((a, b) => (a < b ? 1 : a > b ? -1 : 0));
console.log(values); // 15,10,5,1,0

在这个修改版函数中,如果第一个值应该排在第二个值后面则返回 1,如果第一个值应该排在第二个值前面则返回 -1。交换这两个返回值之后,较大的值就会排在前头,数组就会按照降序排序。当然,如果只是想反转数组的顺序,reverse()更简单也更快。

注意

reverse()和 sort()都返回调用它们的数组的引用。

扩展的比较函数frequently-used

定义一个比较函数,用于对数组进行排序。也可接受一个对象的属性作为入参,实现对象数组根据某一属性进行排序的功能。

试一试

数值数组:

const array = [ 0, 5, 1, 3, 4, 6, 9, 8, 10 ]

排序结果 = [ 0, 1, 3, 4, 5, 6, 8, 9, 10 ]
升序(default)
降序
对象数组:

const array = [ { "name": "song", "age": 18 }, { "name": "xu", "age": 16 }, { "name": "zhang", "age": 20 }, { "name": "li", "age": 19 } ]

排序结果 = [ { "name": "li", "age": 19 }, { "name": "song", "age": 18 }, { "name": "xu", "age": 16 }, { "name": "zhang", "age": 20 } ]
根据
属性进行排序
升序(default)
降序
示例代码
js
/**
 *
 * @param {String | ''} propertyName 对象的属性,为空时取对象的第一个属性
 * @param {Boolean} sort 升序(默认):true 降序:false
 * @returns 返回一个比较函数
 */
const createComparisonFunction =
  (propertyName, sort = true) =>
  (object1, object2) => {
    let value1 = null;
    let value2 = null;
    const typeObj1 = Object.prototype.toString.call(object1).slice(8, -1);
    const typeObj2 = Object.prototype.toString.call(object2).slice(8, -1);
    if (typeObj1 === "Object" && typeObj2 === "Object") {
      if (propertyName) {
        value1 = object1[propertyName];
        value2 = object2[propertyName];
      } else {
        const firstProperty = Object.keys(object1)[0];
        value1 = object1[firstProperty];
        value2 = object2[firstProperty];
      }
    } else {
      value1 = object1;
      value2 = object2;
    }
    if (value1 < value2) {
      return sort ? -1 : 1;
    } else if (value1 > value2) {
      return sort ? 1 : -1;
    } else {
      return 0;
    }
  };