JS中数组的三种去重方法and三种常见的数组排序方法(原生JS)

82 阅读1分钟

数组去重:

一、双for循环方式

原理:依次遍历数组中的每一项,拿当前项和其“后面”的每一项进行比较,如果后面中有和他相同的,则说明这项是重复的,我们把后面中重复的这一项删除掉即可

let arr = [1, 1, 1, 2, 2, 3, 2, 2, 1, 2, 3, 2, 1, 2, 2, 3];
//====外层循环控制每一次拿出一项和其后面的比
//  i < arr.length - 1 最后一项不需要再拿出来了,因为每一次都是和当前项后面的比较,而最后一项后面没有任何的东西,所以也就没有必要再拿出来比较了
for (let i = 0; i < arr.length - 1; i++) {
    // 每一次拿出来要和后面依次比较的那一项
    let item = arr[i];
    //====里层循环控制和当前项后面的每一项逐一比较
    // let j = i + 1 从当前项的后一项开始逐一比较即可
    for (let j = i + 1; j < arr.length; j++) {
        if (item === arr[j]) {
        // 当前项和后面中的某一项相等了,此时我们把后面中的这一项从原始数组中删除掉
        arr.splice(j, 1);
    
        j--; //=>删除完,先让j--,然后在j++,相当于没加没减,下一轮还是从当前索引开始比较,这样防止数组塌陷带来的问题
        }
    }
}


优化后的代码

for (let i = 0; i < arr.length - 1; i++) {
    let item = arr[i];
    for (let j = i + 1; j < arr.length; j++) {
        if (item === arr[j]) {
            // 用最后一项替换当前项
            arr[j] = arr[arr.length - 1];// 原始数组中的顺序会变化,但是不会导致索引前置这种情况(性能好)
            // 最后一项删掉
            arr.length--;
            // 下一轮还和这一项比(因为这一项已经变为最新的最后一项了)
            j--;
        }
    }
}
console.log(arr);

二 、filter过滤

//利用filter
 let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
function unique(arr) {
  return arr.filter(function(item, index, arr) {
    //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
    return arr.indexOf(item, 0) === index;
  });
}
   
        console.log(unique(arr))

三、ES6 中 Set去重

let arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
 //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
//利用ES6 Set去重(ES6中最常用)
function unique (arr) {
  return Array.from(new Set(arr))
}

数组排序

一、快速排序

//快速排序
function quickSort(elements){
    if(elements.length <=1){
      return elements;  
    }
  let pivotIndex=Math.floor(elements.length / 2);
  let pivot=elements.splice(pivotIndex,1)[0];
  let left=[];
  let right=[];
  for(let i=0;i<elements.length;i++){
    if(elements[i] < pivot){
        left.push(elements[i]);
    }else{
       right.push(elements[i]);
    }
  } 
return  quickSort(left).concat([pivot],quickSort(right));
//concat()方法用于连接两个或者多个数组;该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
};
let elements=[3,5,6,8,2,4,7,9,1,10];
document.write(quickSort(elements));

二 、插入排序

//插入排序
function sort(elements){
    // 假设第0个元素是一个有序数列,第1个以后的是无序数列,
    // 所以从第1个元素开始将无序数列的元素插入到有序数列中去
    for (let i =1; i<=elements.length; i++) {
        // 升序
        if(elements[i] < elements[i-1]){
            // 取出无序数列中的第i个作为被插入元素
            let guard=elements[i];
            //记住有序数列的最后一个位置,并且将有序数列的位置扩大一个
            let j=i-1;
            elements[i]=elements[j];
            // 比大小;找到被插入元素所在位置
            while (j>=0 && guard <elements[j]) {
                elements[j+1]=elements[j];
                j--;
            }
            elements[j+1]=guard; //插入
        }
    }
}
let elements=[3,5,6,8,2,4,7,9,1,10];
document.write('没调用之前:'+elements);
document.write('<br>');
sort(elements);
document.write('被调用之后:'+elements);

三、冒泡排序

//冒泡排序
function sort(elements){
    for(let i=0;i<elements.length-1;i++){
       for(let j=0;j<elements.length-1-i;j++){
          if(elements[j] > elements[j+1]){
               let swap=elements[j];
               elements[j]=elements[j+1];
               elements[j+1]=swap;
          }
       }
    }
}
let elements=[3,5,6,8,2,4,7,9,1,10];
console.log('before'+elements);
sort(elements);
console.log('after'+elements);