JS中數組去重的三種方法


JS中數組去重的三種方法


數組去重的方式有很多種,我們先拿出3種比較簡單的進行學習;

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

思維導圖


JS中數組去重的三種方法


一、雙FOR循環方式

原理:依次遍歷數組中的每一項,拿當前項和其“後面”的每一項進行比較,如果後面中有和他相同的,則說明這項是重複的,我們把後面中重複的這一項刪除掉即可

<code>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++,相當於沒加沒減,下一輪還是從當前索引開始比較,這樣防止數組塌陷帶來的問題

}
}
}
複製代碼/<code>

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

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

解決完splice引起的塌陷問題後我們已經可以實現想要的效果,但是根據上圖我們可以知道,

在刪除重複項後後面每一項的索引都會向前提一位,這樣(如果刪除的這一項後面還有1000萬項,那麼這1000萬項的索引都要向前提一位)會大大的消耗性能, 所以我們需要做進一步的優化處理;

  • 第二點:性能優化


JS中數組去重的三種方法


2、優化後的代碼如下:

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

二、對象鍵值對的方式

原理:利用對象中屬性名不能重複的特點,先建立一個空對象,然後依次循環數組中的每一項,把此項作為obj對象的屬性名和屬性值,在添加的時候,如果這個屬性名對應的值已經存在,說明此項重複,刪除掉此項

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


JS中數組去重的三種方法


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

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

三、indxOf檢測的方式

原理:創建一個新數組,遍歷原數組,如果新數組中沒有那一項的話,就把它push進去

<code>let arr=[1,2,1,3,3,2,3];
let newAry=[];
/*把原數組中的每一項,只要在新數組中沒存在過,我們就把它放進去,最後newAry就是咱們最終要的數組*/

for(let i=0;i<arr.length> let item=arr[i];
if(newAry.indexOf(item)==-1){
newAry.push(item);
}
}
arr = newAry;
console.log(arr);
複製代碼/<arr.length>/<code>

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

四、ES6利用Set方式

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

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


分享到:


相關文章: