ES11 中的 Array.prototype.sort 排序方法的技巧和注意事项

阅读时长 9 分钟读完

Array.prototype.sort() 是 JavaScript 中一个十分常用的数组排序方法。但是这个方法在浏览器和 Node.js 中的排序效果可能会有所差异,在 ES11 中也加入了一些新的特性,因此需要我们注意一些技巧和注意事项以便更好地使用这个方法。本篇文章将会对这些细节进行详尽的讲解和示例代码演示。

基础使用

sort() 方法的基础用法很简单,它可以在原地对数组进行排序,即修改原数组而不返回新的数组。排序方法默认是按照 Unicode 码点进行排序的,如果希望按照数字大小,需要传入一个比较函数。

示例如下:

以上代码中,我们按照数字从小到大对数组进行排序,输出的结果为 [1, 2, 3, 8, 15]。需要注意的是,sort() 方法会直接修改原数组,因此需要注意是否需要保留原数组。

注意事项

  1. 排序可能会改变元素顺序,如果需要保留元素顺序,需要通过浅拷贝或深拷贝来进行排序。
  2. 比较函数需要比较的是排序关键字,而不是对应的数组下标或值。
  3. 比较函数需要是稳定的,即对于相等的元素,排序后它们的顺序不会改变。

接下来,我们将通过示例代码来一一介绍这些注意事项。

1. 排序可能会改变元素顺序

示例代码如下:

-- -------------------- ---- -------
----- --- - -
  - --- -- ----- ------- --
  - --- -- ----- ----- --
  - --- -- ----- --------- --
--

-- -- ---- ----
------------ -- -- ------------------------------
-----------------
-- ---- - --- -- ----- ------- -- - --- -- ----- ----- -- - --- -- ----- --------- - -

以上代码中,我们按照 name 字段排序,但是输出的结果与期望的不一样,原因是 sort() 方法直接改变了原始数组。我们可以通过浅拷贝来避免这个问题:

-- -------------------- ---- -------
----- --- - -
  - --- -- ----- ------- --
  - --- -- ----- ----- --
  - --- -- ----- --------- --
--

-- -- ---- ----
----- ------ - ----------------- -- -- ------------------------------
-----------------
-- ---- - --- -- ----- ------- -- - --- -- ----- ----- -- - --- -- ----- --------- - -
--------------------
-- ---- - --- -- ----- ------- -- - --- -- ----- ----- -- - --- -- ----- --------- - -

以上代码中,我们通过浅拷贝创建了一个新数组 newArr,并对其进行排序,同时保留了原数组 arr 的顺序。

2. 比较函数需要比较的是排序关键字

示例代码如下:

-- -------------------- ---- -------
----- --- - -
  - --- -- ----- ------- --
  - --- -- ----- ----- --
  - --- -- ----- --------- --
--

-- -------
----- ----------- - --- -- -- ------ - -------
----------------------
-----------------
-- ---- - --- -- ----- ------- -- - --- -- ----- ----- -- - --- -- ----- --------- - -

以上代码中,我们定义了一个错误的比较函数,试图按照 name 字段排序,但是输出的结果却没有进行排序。原因是比较函数应该是一个用来比较排序关键字,而不是对应的数组下标或值。我们需要改用如下的比较函数:

以上代码中,我们通过 localeCompare() 方法来比较字符串大小,实现了按照 name 字段排序。

3. 比较函数需要是稳定的

稳定排序是指在排序后,对于相等的元素,它们的顺序不会改变。如果不保证稳定性,排序后可能得到不同的结果,这对于一些需要排序的应用场景来说是无法接受的。在 JavaScript 中,sort() 方法默认是不稳定的。

示例代码如下:

-- -------------------- ---- -------
----- --- - -
  - --- -- ----- ----- --
  - --- -- ----- ------- --
  - --- -- ----- ----- --
--

-- -----
------------ -- -- ------------------------------
-----------------
-- ---- - --- -- ----- ------- -- - --- -- ----- ----- -- - --- -- ----- ----- - -

以上代码中,我们试图按照 name 字段进行排序,但是得到的结果却是不稳定的。这个问题可以通过以下两种方法解决:

  1. 添加额外的排序关键字,比如按照 id 字段进行排序:

    以上代码中,我们首先按照 name 字段进行排序,如果 name 字段相同,则按照 id 字段进行排序。这样可以保证排序的稳定性。

  2. 使用稳定排序算法,比如归并排序:

    -- -------------------- ---- -------
    ----- --------- - ----- ------------ -- -
      ----- ----- - ------ ------ -- -
        --- ------ - ---
        --- - - --
        --- - - --
        ----- -- - ----------- -- - - ------------- -
          -- --------------------- --------- -- -- -
            ---------------------
            ----
          - ---- -
            ----------------------
            ----
          -
        -
        ------ ----------------------------------------------------
      --
      ----- ---- - ----- -- -
        -- ----------- -- -- -
          ------ ----
        -
        ----- --- - --------------------- - ---
        ----- ---- - ------------ -----
        ----- ----- - ---------------
        ------ ----------------- -------------
      --
      ------ ---------------
    --
    
    --- - -------------- --- -- -- ------------------------------
    -----------------
    -- ---- - --- -- ----- ------- -- - --- -- ----- ----- -- - --- -- ----- ----- - -

    以上代码中,我们实现了一个归并排序算法,并将其应用到数组排序中,可以得到稳定的排序结果。

ES11 的新特性

在 ES11 中,sort() 方法添加了返回完整排序结果的功能。我们可以通过 Array.prototype.flatMap() 方法来实现这个功能。

示例代码如下:

-- -------------------- ---- -------
----- --- - -
  - --- -- ----- ----- --
  - --- -- ----- ------- --
  - --- -- ----- --------- --
--

-- ---
----- ------- - ----- ------------ -- ------------------- -- -------------------------
------------------------ --- -- -- -------------------------------
-- ---- - --- -- ----- ------- -- - --- -- ----- ----- -- - --- -- ----- --------- - -

以上代码中,我们定义了一个 newSort() 方法,利用了 Array.prototype.flatMap() 方法的特性,返回了完整排序后的结果。

总结

Array.prototype.sort() 是 JavaScript 中的一个常用数组排序方法,但是在使用中需要注意排序对原始数组的影响、比较函数需要比较的是排序关键字、比较函数需要是稳定的等一系列问题。在 ES11 中,sort() 方法添加了新的返回完整排序结果的功能,可以更方便地使用。在实际应用中,我们需要根据具体场景选择不同的排序算法,并注意使用时的注意事项。

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

纠错
反馈