JS中數組去重的三種方法

數組去重的方式有不少種,咱們先拿出3種比較簡單的進行學習;javascript

  • 1.雙FOR循環(拿當前項和後面的每一項進行比較,重點:數組塌陷和SPLICE刪除的優化)
  • 2.對象的鍵值對方式
  • 3.indxOf檢測的方式

思惟導圖

1、雙FOR循環方式

原理:依次遍歷數組中的每一項,拿當前項和其「後面」的每一項進行比較,若是後面中有和他相同的,則說明這項是重複的,咱們把後面中重複的這一項刪除掉便可java

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++,至關於沒加沒減,下一輪仍是從當前索引開始比較,這樣防止數組塌陷帶來的問題
        }
    }
}
複製代碼

一、用splice刪除需注意的兩點:

  • 第一點:數組塌陷問題:以用--解決

解決完splice引發的塌陷問題後咱們已經能夠實現想要的效果,可是根據上圖咱們能夠知道,數組

  • 在刪除重複項後後面每一項的索引都會向前提一位,這樣(若是刪除的這一項後面還有1000萬項,那麼這1000萬項的索引都要向前提一位)會大大的消耗性能,
  • 因此咱們須要作進一步的優化處理;
  • 第二點:性能優化

二、優化後的代碼以下:

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);
複製代碼

2、對象鍵值對的方式

原理:利用對象中屬性名不能重複的特色,先創建一個空對象,而後依次循環數組中的每一項,把此項做爲obj對象的屬性名和屬性值,在添加的時候,若是這個屬性名對應的值已經存在,說明此項重複,刪除掉此項瀏覽器

let arr = [1, 2, 3, 1, 1, 4, 2, 3];
let obj = {};
for (let i = 0; i < arr.length; i++) {
    // 把每一次循環獲得的當前項,做爲對象的屬性名和屬性值存儲進去
    let item = arr[i];
    if (obj[item] !== undefined) {
        // 證實對象中有這個屬性(也就是以前存儲過,數組中以前就有這個值),當前值是重複的,咱們須要把當前這項的值刪掉便可
        arr[i] = arr[arr.length - 1];
        arr.length--;
        i--;
        continue;
    }
    obj[item] = item;
}
console.log(arr);
複製代碼

對象鍵值對的方式的優缺點

  • 優勢:
    • 只有一個循環,因此性能很好
  • 缺點:
    • 1.若是數組中出現對象則存在問題(由於對象的屬性名不能是對象,遇到會轉換爲字符串);
    • 2.若是數組中存在數字10和字符串'10',則也會認爲是重複的(對象中的屬性名是數字和字符串沒啥區別);
    • 3.數組中的值若是是undefined可能也會出現問題....

3、indxOf檢測的方式

原理:建立一個新數組,遍歷原數組,若是新數組中沒有那一項的話,就把它push進去性能優化

let arr=[1,2,1,3,3,2,3];
let newAry=[];
  /*把原數組中的每一項,只要在新數組中沒存在過,咱們就把它放進去,最後newAry就是我們最終要的數組*/
  
for(let i=0;i<arr.length;i++){
       let item=arr[i];
       if(newAry.indexOf(item)==-1){
        newAry.push(item);
       }
   }
arr = newAry;
console.log(arr);
複製代碼

缺點:indexOf低版本瀏覽器不兼容

4、ES6利用Set方式

/* ES6中沒有提供現成的去重辦法,可是提供了一些去重的方式 :Set數據結構*/
let obj = { y: 200 };
let arr = [obj, 1, 2, 3, 1, obj, 1, 4, 2, 3, '3', { x: 100 }, { x: 100 }];
arr = Array.from(new Set(arr));
console.log(arr);
複製代碼

缺點:低版本瀏覽器不兼容

相關文章
相關標籤/搜索