ES10 中新增 stable-sort 对数组进行稳定排序

JavaScript 的数组是开发者进行数据处理时最常用的一种数据结构。因此,在处理数据过程中,对数组进行排序是非常常见的操作。ES6 使用 Timsort 算法对数组进行排序,但它无法保证排序的稳定性。在 ES10 中,引入了新的算法和方法,可以实现对数组进行稳定排序,这就是 stable-sort。

稳定排序和不稳定排序

稳定排序是指,在排序的时候,相等的元素在排完序之后,它们的相对位置不会改变。不稳定排序则表示在排序过程中,相等的元素可能会在排序后改变其相对位置。

下面是一个使用不稳定排序的例子:

const data = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 20 },
  { name: 'Charlie', age: 25 },
];

data.sort((a, b) => a.age - b.age);

console.log(data);
// Output: [{ name: 'Bob', age: 20 }, { name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }]

上述代码使用 sort 方法对 data 数组进行排序。按照 age 属性排序,但在 age 相等的情况下,sort 方法并不保证元素的相对位置不变。

稳定排序就非常重要了,它可以用于保持代码的可预测性。在某些场景下,我们需要对数组中的元素进行多次排序。如果排序是不稳定的,那么就有可能导致顺序被打乱,造成意外结果。

ES10 的 stable-sort 方法

ES10 中新增了 stable-sort 方法,它可以实现稳定排序。

stable-sort 方法的语法如下:

array.stableSort(compareFunction);

其中,compareFunction 是一个比较函数。与 sort 方法类似,compareFunction 接受两个参数,表示要比较的元素,返回值表示它们的大小关系。但 stable-sort 会根据比较函数的返回值进行排序,同时保证稳定性。

下面是一个使用 stable-sort 方法的例子:

const data = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 20 },
  { name: 'Charlie', age: 25 },
];

data.stableSort((a, b) => a.age - b.age);

console.log(data);
// Output: [{ name: 'Bob', age: 20 }, { name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }]

使用 stableSort 方法,排序的相等元素的相对位置得到了保障。这是一种更符合直觉的排序方式。

总结

在处理数据时,使用稳定排序是非常重要的。为此,ES10 中新增的 stable-sort 方法可以让我们更加方便地实现稳定排序,避免因为排序的问题引发更严重的后果。

在实际开发过程中,我们需要根据具体需求选择使用 stable-sort 方法或其他排序方法,来让我们的代码更具稳定性和可维护性。

示例代码

Array.prototype.stableSort =
  (function () {
    const map = new WeakMap();
    return function (compareFunction) {
      if (typeof compareFunction !== 'function') {
        compareFunction = (a, b) => {
          a = a + '';
          b = b + '';
          return a < b ? -1 : a > b ? 1 : 0;
        };
      }
      let index = 0;
      map.set(this, this.map((item, index) => ({ item, index })));
      this.sort((a, b) => {
        const result = compareFunction(a, b);
        if (result !== 0) {
          return result;
        } else {
          const aIndex = map.get(this)[index++].index;
          const bIndex = map.get(this)[index++].index;
          return aIndex - bIndex;
        }
      });
    };
  })();

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a56857add4f0e0ffdf3b86


纠错反馈