js中数组sort方法的使用和模拟实现

js中数组sort方法的使用和模拟实现

一、定义

sort方法是对数组的元素进行排序,并返回对相同数组的引用。

二、语法

sort() // 无参数直接调用
sort(compareFn) // 传一个回调函数

三、参数

compareFn 可选

传入的回调函数根据返回值决定排序的顺序。

a compareFn函数的第一个用于比较的元素。是用于的排序的数组中的元素。
b compareFn函数的第二个用于比较的元素。是用于的排序的数组中的元素。

四、返回值

返回经过排序的原始数组的引用,也就是说原数组同时也会改变。

五、详细描述

sort方法可以对数组进行排序,并且返回原数组的引用(也就是说原数组同时会改变)。

sort方法的参数是可选的,如果不传的时候会将数组的元素转为字符串,然后根据每个字符的 Unicode 码位值进行排序。

如果传递了排序规则函数compareFn那么数组每一项非undefined的元素将会按照compareFn函数的返回值进行排序。(所有的 undefined 元素都会被排序到数组的末尾,并且不调用 compareFn)。

compareFn函数里面有两个参数都是原数组中的元素,他们的排序规则如下:

  • 如果compareFn返回值大于0,那么 a 排在 b 后。
  • 如果compareFn返回值等于0,那么就是保持a, b现在顺序不变。
  • 如果compareFn返回值小于0,那么 b 排在 a 后。

compareFn函数的规则还有很多详细了解可以参考这篇文章https://zhuanlan.zhihu.com/p/379301236。

我们使用时只需要知道compareFn(a, b)的返回值 为a - b 代表了升序,而b - a 代表了降序。

六、使用示例

不传入compareFn排序参数

    // 不传入compareFn参数
    const list1 = [1, 100, 10, 62, 8];
    const list2 = ['blue', 'yellow', 'red', 'green'];
    const list3 = [1, 100, 10, 62, 8, '50', '1000'];
    const list4 = [{ num: 4 }, { num: 10 }, { num: 62 }, { num: 100 }];

    console.log(list1.sort()); // [1, 10, 100, 62, 8]
    console.log(list2.sort()); // ['blue', 'green', 'red', 'yellow']
    console.log(list3.sort()); // [1, 10, 100, '1000', '50', 62, 8]
    console.log(list4.sort()); // [{ num: 4 }, { num: 10 }, { num: 62 }, { num: 100 }];
    
    传入compareFn排序参数
    // 传入compareFn参数
    const list1 = [1, 100, 10, 62, 8];
    const list2 = ['blue', 'yellow', 'red', 'green'];
    const list3 = [1, 100, 10, 62, 8, '50', '1000'];
    const list4 = [{ num: 4 }, { num: 10 }, { num: 62 }, { num: 100 }];
    // 传入升序参数
    const compareFn1 = (a, b) => a - b;
    console.log(list1.sort(compareFn1)); // [1, 8, 10, 62, 100]
    console.log(list2.sort(compareFn1)); //  ['blue', 'yellow', 'red', 'green']
    console.log(list3.sort(compareFn1)); // [1, 8, 10, '50', 62, 100, '1000']
    // 数组对象需要使用里面的一项值来判断
    console.log(list4.sort((a, b) => a.num - b.num)); // [{ num: 4 }, { num: 10 }, { num: 62 }, { num: 100 }]

    // 传入降序参数
    const compareFn2 = (a, b) => b - a;
    console.log(list1.sort(compareFn2)); // [100, 62, 10, 8, 1]
    console.log(list2.sort(compareFn2)); // ['blue', 'yellow', 'red', 'green']
    console.log(list3.sort(compareFn2)); // ['1000', 100, 62, '50', 10, 8, 1]
    // 数组对象需要使用里面的一项值来判断
    console.log(list4.sort((a, b) => b.num - a.num)); // [{ num: 100 }, { num: 62 }, { num: 10 }, { num: 4 }]
    

七、模拟实现

 Array.prototype.mySort = function (compareFn) {
   if (compareFn && typeof compareFn !== 'function')
     throw new Error('compareFn必须是函数或者undefined');
   // 只有一个数据或者空数组时直接返回
   if (this.length < 2) return this;
   // 不传参数时
   if (!compareFn) {
     // 使用冒泡排序
     for (let index = 0; index < this.length; index++) {
       for (let j = 0; j < this.length - 1 - index; j++) {
         // 转换为字符串升序比较
         if (String(this[j + 1]) < String(this[j])) {
           const exchange = this[j];
           this[j] = this[j + 1];
           this[j + 1] = exchange;
         }
       }
     }
     return this;
   }

   // 快速排序定义
   const quickSort = function (arr, left, right) {
     if (left >= right) return;

     const pivotValue = arr[right];
     let partitionIndex = left;

     for (let i = left; i < right; i++) {
       const result = compareFn(arr[i], pivotValue);
       // 根据返回结果处理数组的顺序
       if (result < 0 || isNaN(result)) {
         [arr[i], arr[partitionIndex]] = [arr[partitionIndex], arr[i]];
         partitionIndex++;
       }
     }

     [arr[right], arr[partitionIndex]] = [arr[partitionIndex], arr[right]];

     quickSort(arr, left, partitionIndex - 1);
     quickSort(arr, partitionIndex + 1, right);
   };

   // 传入compareFn参数时调用快速排序算法对新数组进行排序
   quickSort(this, 0, this.length - 1);

   return this;
 };
 

八、验证

不传入compareFn排序参数验证

    // 传入compareFn参数
    const list1 = [1, 100, 10, 62, 8];
    const list2 = ['blue', 'yellow', 'red', 'green'];
    const list3 = [1, 100, 10, 62, 8, '50', '1000'];
    const list4 = [{ num: 4 }, { num: 10 }, { num: 62 }, { num: 100 }];

    console.log(list1.mySort()); // [1, 10, 100, 62, 8]
    console.log(list2.mySort()); // ['blue', 'green', 'red', 'yellow']
    console.log(list3.mySort()); // [1, 10, 100, '1000', '50', 62, 8]
    console.log(list4.mySort()); // [{ num: 4 }, { num: 10 }, { num: 62 }, { num: 100 }];
    

传入compareFn排序参数验证

    // 传入compareFn参数
    const list1 = [1, 100, 10, 62, 8];
    const list2 = ['blue', 'yellow', 'red', 'green'];
    const list3 = [1, 100, 10, 62, 8, '50', '1000'];
    const list4 = [{ num: 4 }, { num: 10 }, { num: 62 }, { num: 100 }];

    // // 传入升序参数
    const compareFn1 = (a, b) => a - b;
    console.log(list1.mySort(compareFn1)); // [1, 8, 10, 62, 100]
    console.log(list2.mySort(compareFn1)); //  ['blue', 'yellow', 'red', 'green']
    console.log(list3.mySort(compareFn1)); // [1, 8, 10, '50', 62, 100, '1000']
    // 数组对象需要使用里面的一项值来判断
    console.log(list4.mySort((a, b) => a.num - b.num)); // [{ num: 4 }, { num: 10 }, { num: 62 }, { num: 100 }]

    // // 传入降序参数
    const compareFn2 = (a, b) => b - a;
    console.log(list1.mySort(compareFn2)); // [100, 62, 10, 8, 1]
    console.log(list2.mySort(compareFn2)); // ['blue', 'yellow', 'red', 'green']
    console.log(list3.mySort(compareFn2)); // ['1000', 100, 62, '50', 10, 8, 1]
    // 数组对象需要使用里面的一项值来判断
    console.log(list4.mySort((a, b) => b.num - a.num)); // [{ num: 100 }, { num: 62 }, { num: 10 }, { num: 4 }]
    
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值