diff --git a/docs/array.md b/docs/array.md index 08dd118..d1f123f 100644 --- a/docs/array.md +++ b/docs/array.md @@ -32,7 +32,7 @@ const numbers = [4, 38]; add(...numbers) // 42 ``` -上面代码中,`array.push(...items)`和`add(...numbers)`这两行,都是函数的调用,它们的都使用了扩展运算符。该运算符将一个数组,变为参数序列。 +上面代码中,`array.push(...items)`和`add(...numbers)`这两行,都是函数的调用,它们都使用了扩展运算符。该运算符将一个数组,变为参数序列。 扩展运算符与正常的函数参数可以结合使用,非常灵活。 @@ -947,3 +947,43 @@ for (let i of arr) { ``` 由于空位的处理规则非常不统一,所以建议避免出现空位。 + +## Array.prototype.sort() 的排序稳定性 + +排序稳定性(stable sorting)是排序算法的重要属性,指的是排序关键字相同的项目,排序前后的顺序不变。 + +```javascript +const arr = [ + 'peach', + 'straw', + 'apple', + 'spork' +]; + +const stableSorting = (s1, s2) => { + if (s1[0] < s2[0]) return -1; + return 1; +}; + +arr.sort(stableSorting) +// ["apple", "peach", "straw", "spork"] +``` + +上面代码对数组`arr`按照首字母进行排序。排序结果中,`straw`在`spork`的前面,跟原始顺序一致,所以排序算法`stableSorting`是稳定排序。 + +```javascript +const unstableSorting = (s1, s2) => { + if (s1[0] <= s2[0]) return -1; + return 1; +}; + +arr.sort(unstableSorting) +// ["apple", "peach", "spork", "straw"] +``` + +上面代码中,排序结果是`spork`在`straw`前面,跟原始顺序相反,所以排序算法`unstableSorting`是不稳定的。 + +常见的排序算法之中,插入排序、合并排序、冒泡排序等都是稳定的,堆排序、快速排序等是不稳定的。不稳定排序的主要缺点是,多重排序时可能会产生问题。假设有一个姓和名的列表,按照“先姓,后名”进行排序。开发者可能会先按名字排序,再按姓氏进行排序。如果排序算法是稳定的,这样也可以达到“先姓,后名”的排序效果。如果是不稳定的,就不行。 + +早先的 ECMAScript 没有规定,`Array.prototype.sort()`的默认排序算法是否稳定,留给浏览器自己决定,这导致某些实现是不稳定的。[ES2019](https://github.com/tc39/ecma262/pull/1340) 明确规定,`Array.prototype.sort()`的默认排序算法必须稳定。这个规定已经做到了,现在 JavaScript 各个主要实现的默认排序算法都是稳定的。 +