ES3
var arr = [5, 3, 1, 2, 6, 4];
var newArr = arr.sort();
// 返回原数组的引用,不进行数组引用赋值
newArr === arr // true
使用原地算法
在不同浏览器的引擎实现方案不一样
- V8
- arr.length <= 10 插入排序
- arr.length >10 快速排序
- Mozilla
- 归并排序
- Webkit
- 使用C++ QSort 快速排序的理念
// sort 并不会按照数字大小进行排序
var arr = [5, 3, 1000, 1, 6];
arr.sort(); // [1, 1000, 3, 5, 6]
var arr = ['b', 'x', 'i', 'm', 'a', 'd'];
arr.sort(); // ["a", "b", "d", "i", "m", "x"];
var arr = [true, false];
arr.sort(); // [false, true];
是以 toString -> 数组元素 -> 字符串
这个字符串是 DOMString -> UTF-16字符串实现 -> 映射到String -> 构建字符串
string -> UTF-16字符串 -> String/DOMString 的实例
即是按照 UTF-16 的编码顺序来进行排序
为什么要转成字符串
如果是仅限一种类型排序的话,sort 功能性就太弱
用字符串和字符编码集结合在一起形成排序规则,这样可以排序的范围就大了
// 字符串的逐个字符进行编码位的排序
var arr = ['abc', 'aba'];
arr.sort(); // ["aba", "abc"]
参数 compareFunction
compareFunction就是自己写排序规则
比较函数方法,有两个参数
- FElement
- SElement
返回
- 负数 a 就排在 b 前面
- 正数 b 就排在 a 前面
- 0 a 与 b 不进行排序
纯数字比较
var arr = [5, 1, 2, 4, 6, 3, 3];
arr.sort() // [1, 2, 3, 3, 4, 5, 6]
arr.sort(function (a, b){
// 没有写排序规则, 不进行任何排序操作
})
arr.sort(function (a, b){
if(a < b) {
return -1;
}
if(a > b) {
return 1;
}
if(a === b) {
return 0;
}
// 升序(小到大)
return a - b;
// 降序(大到小)
return b - a;
// 反转
return -1;
// 有作排序,但结果不变
return 1;
// 不变
return 0;
// 乱序
return Math.random() - 0.5;
})
compareFunction 必须对相同的输入有相同返回结果,结果不肯定(近似纯函数)
非 ASCII 字符串排序
对于字符串的比较要用 String.prototype.localeCompare() 方法来进行比较
var arr = ['我', '爱', '你'];
arr.sort((a, b) => {
return a.localeCompare(b);
});
大小写不一致的情况下都转为大写或小写
var arr = [
'zhangsan',
'Xiaoye',
'MIKE',
'tony'
]
// 这样子的话,每次比较形参都要进行一次转换,对性能负载较大
arr.sort(() => {
var _a = a.toLowerCase(),
_b = b.toLowerCase();
if(_a < _b) {
return -1;
}
if(_a > _b) {
return 1;
}
return 0
});
// 这时应该使用 map 先进行一次性在大写或小写化的对象映射,再进行比较
var newArr = arr.map(function(item, index){
var it = {
index,
value: item.toLowerCase()
}
return it;
})
newArr.sort((a, b) => {
if(a.value > b.value) {
return 1;
}
if(a.value < b.value) {
return -1;
}
return 0;
});
var res = newArr.map(function (item){
return arr[item.index];
})