Array.sort()方法MDN的部分说明
sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的
语法
arr.sort([compareFunction])
Array.sort() demo
const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// expected output: Array ["Dec", "Feb", "Jan", "March"]
const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// expected output: Array [1, 100000, 21, 30, 4]
Array.sort()方法使用说明
- 不传任何参数
arr = [7, 10, 6, 8, 5]
console.log(arr.sort()) //[10, 5, 6, 7, 8]
怎么不按套路出牌,这不是我想要的结果……别急,我们可以定义任意规则,让它按照我们想要的结果排序。 默认是按ASK码排序,10识别不是数字十,而是,1和0,按位对比,如果第一位相等,则进行下一位的对比。
- 传入一个函数作为参数,自定义排序规则
sort方法可以传一个function,来定义我们需要的排序规则
arr.sort(function (a, b){
//自定义规则
})
- 必需写两个形参
- 函数返回值决定升序还是降序
-
当返回值为负数或零时,位置不变
-
返回值为正数时,位置调换位置
-
Array.sort()方法的内部原理分析
来看下面的例子
arr = [7, 10, 6, 8, 5]
arr.sort(function (a, b) {
return a - b
})
console.log(arr)
假设b >= a,此时a - b <= 0 ,返回值为负数或零,参数位置不变,也就是说大的数b排在后面,排序结果为升序。
假设a > b,此时a - b > 0 ,返回值为正数,参数位置调换,也就是说a、b位置调换,大的数a排在后面,结果为升序
排序过程使用原地算法,过程如下:
第一轮:
[7, 10, 6, 8, 5]
-
首先,数组第一位跟第二位对比,
a = 7,b = 10,return a - b为负,位置不变。数组为[7, 10, 6, 8, 5] -
接下来,数组第一位与第三位对比,
a = 7,b = 6,return a - b为正数,调换位置,数组变为[6, 10, 7, 8, 5] -
其次,数组的第一位与第四位对比,
a = 6,b = 8,return a - b为负数,位置不变,数组为[6, 10, 7, 8, 5] -
最后,数组的第一位与第五位对比,
a = 6,b = 5,return a - b为正数,位置调换,数组变为[5, 10, 6, 8, 7]
第一轮结束,最小的数变到了第一位
第二轮
[5, 10, 6, 8, 7]
- 首先,数组第二位跟第三位对比,
a = 10,b = 6,return a - b为正,位置调换。 - 然后第三位与第四位对比,以此类推。
第二轮结束第二小的数变到了第二位。第三轮结束,第三小的数换到了第三位……
Array.sort()方法源码实现
Array.prototype.mySort = function (fn = defaultFn) {
var len = this.length
var tmp
for (let i = 0; i < len - 1; i++) {
for (let j = i + 1; j < len; j++) {
if (fn(this[i], this[j]) > 0) {
tmp = this[i]
this[i] = this[j]
this[j] = tmp
}
}
}
return this
}
function defaultFn(cur, next) {
if (String(cur) > String(next)) {
return 1
} else {
return -1
}
}
总结:
- 结论
arr.sort(function (a, b){
return a - b //升序
// return b - a //降序
})
- 个人的总结
什么时候升序,什么时候降序,刚开始容易混乱.只需记住,返回负数时,位置不变。把任意满足这一情况的特殊值代入,前面的大就是降序,后面的大就是升序。 (PS:当然记返回正数的情况也一样,记住一种情况,然后推导另一种情况,信息量减少了50%,不仅记得牢,还不会乱,效率提升不止50%)
function (a, b) { return a - b }
我要让返回值为负,此时b > a,(a, b)位置不变,大的值b在后面,为升序。
当return b - a,要让返回值为负,此时a > b,(a, b)位置不变,大的值a在前面,为降序