數組去重方法總結(JavaScript 記錄)

来源:https://www.cnblogs.com/ikunblog/archive/2023/07/23/17576150.html
-Advertisement-
Play Games

【JavaScript寫法】數組去重 在進行項目開發的時候,有時候需要把一些前端的數組進行去重處理,得到一個去重後的數據,然後再進行相關的操作,這也是在前端面試中經常出現的問題 ...


在進行項目開發的時候,有時候需要把一些前端的數組進行去重處理,得到一個去重後的數據,然後再進行相關的操作,這也是在前端面試中經常出現的問題

數組去重的多種方法:

  1. 利用 ES6 Set 去重
  2. 利用 for 嵌套 for,然後 splice 去重
  3. 利用 indexOf 去重
  4. 利用 sort() 去重
  5. 利用對象的屬性不能相同的特點進行去重
  6. 利用 includes 去重
  7. 利用 hasOwnProperty 去重
  8. 利用 filter 去重
  9. 利用遞歸去重
  10. 利用 Map 數據結構去重
  11. 利用 reduce+includes 去重
  12. [...new Set(arr)] 去重

數組去重

利用 ES6 Set 去重數組

Set 自帶的特性,數據不重覆

Array.from() 方法將 Set 對象轉換為數組,並返回該數組作為去重後的新數組。

時間複雜度為 O(n),因為 Set 對象只需要遍歷一次原數組即可完成去重操作

註:無法判斷{}重覆的情況

const _deleteRepeat = array => {
    return Array.from(new Set(array))
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log("去重後:=>",_deleteRepeat(arr));
//去重後:=> [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

利用 for 嵌套 for,然後 splice 去重

雙層迴圈,外層迴圈元素, 內層迴圈時比較值。值相同時,則刪去這個值。(比較相鄰兩個數如果重覆用 splice 刪除)

時間複雜度為 O(n^2),因為兩層迴圈需要對所有元素進行比較。因此,這種方法在處理大型數組時可能會導致性能問題。⚠️

註:無法判斷NaN{} 重覆的情況

const _deleteRepeat = array => {
    for (let i = 0; i < array.length; i++) {
        for (let j = i + 1; j < array.length; j++) {
            if (array[i] === array[j]) {
                array.splice(j, 1);
                j --;
            }
        }
    }
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
_deleteRepeat(arr)
console.log(arr)
// [ 1, 15, "abc", true, false, undefined, null, NaN, NaN, {}, {}]

利用 indexOf 去重

新建⼀個空的結果數組, for 迴圈原數組, 判斷結果數組是否存在當前元素, 如果有相同的值則跳過,不相同則 push 進數組

時間複雜度為 O(n^2),因為 indexOf() 方法需要對所有元素進行比較。因此,這種方法在處理大型數組時可能會導致性能問題。⚠️

註:無法判斷NaN{} 重覆的情況

const _deleteRepeat = array => {
    // 聲明一個空數組,用indexOf尋找如果沒有該元素則加入新數組
    let newArray = [];
    array.forEach(item => {
        if(newArray.indexOf(item) === -1) {
            newArray.push(item)
        }
    });
    return newArray;
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr));
// [ 1, 15, "abc", true, false, undefined, null, NaN, NaN, {}, {} ]

利用 sort() 去重

利用sort()排序方法,然後根據排序後的結果進行遍歷及相鄰元素比對

時間複雜度為 O(n log n),因為需要對所有元素進行排序操作。因此,這種方法在處理大型數組時可能會導致性能問題。⚠️

註:無法判斷NaN{} 重覆的情況

const _deleteRepeat = array => {
    if (!Array.isArray(array)) {
        console.log("type error")
        return
    }
    array = array.sort();
    let newArray = [array[0]]
    for (let i = 1; i < array.length; i++) {
        if (array[i] !== array[i - 1]) {
            newArray.push(array[i])
        }
    }
    return newArray
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, NaN, NaN, {}, {}, "abc", false, null, true, undefined ]

利用對象的屬性不能相同的特點進行去重

它會遍歷輸入的數組,將每個元素作為對象的屬性名,如果該屬性名在對象中不存在,則將其添加到對象中並將該元素添加到新數組中;如果該屬性名已經存在,則不進行任何操作。最終返回去重後的新數組。

註:只能去除數組中的重覆值,而不能去除數組中的重覆元素(即包含多個值的元素)。如果需要去除數組中的重覆元素,可以使用其他方法,比如使用 Set 數據結構或者雙重迴圈等。⚠️

const _deleteRepeat = array => {
    if (!Array.isArray(array)) {
        console.log("type error")
        return
    }
    let newArray = [];
    let obj = {};
    array.forEach(item => {
        if(!obj[item]) {
            obj[item] = true;
            newArray.push(item);
        }
    })
    return newArray;
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {} ]

利用 includes 去重

聲明一個空數組,用 includes 尋找如果沒有該元素則加入新數組

時間複雜度為 O(n^2),因為需要對所有元素進行比較和查找操作。因此,這種方法在處理大型數組時可能會導致性能問題。⚠️

註:無法判斷{} 重覆的情況

const _deleteRepeat = array => {
    let newArray = [];
    array.forEach(item => {
        if (!newArray.includes(item)) {
            newArray.push(item)
        }
    });
    return newArray
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

利用 hasOwnProperty 去重

利用 hasOwnProperty 檢查對象是否具有指定屬性

typeof {}+{} 為 object[object Object],判斷有沒有空對象,已經有的話 return false,沒有就作為對象的屬性加進去,值為 true

時間複雜度為 O(n^2),因為需要對所有元素進行比較和查找操作。因此,這種方法在處理大型數組時可能會導致性能問題。⚠️

const _deleteRepeat = array => {
    let newArray = [];
    let obj = {};
    newArray = array.filter(item => {
        return obj.hasOwnProperty(typeof item + item) ? false : obj[typeof item +item] = true
    });
    return newArray
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {} ]

利用 filter 去重

該函數使用了 filter() 方法來篩選出數組中的唯一元素。在 filter() 方法中,傳入了一個回調函數,該回調函數接受兩個參數:item(當前遍歷到的元素)和 index(當前元素的索引)。

在回調函數內部,我們使用indexOf() 方法查找該元素在原數組中第一次出現的位置。如果該位置與當前迴圈的索引相同,則說明該元素是第一次出現,需要保留;否則,說明該元素已經出現過一次,需要過濾掉。

註:無法判斷{} 重覆的情況(無法判斷 NaN)

const _deleteRepeat = array => {
    return array.filter((item, index) => {
        return array.indexOf(item) === index
    })
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, {}, {} ]

利用遞歸去重

時間複雜度是 O(n^2),因為在每次遞歸調用時都需要遍歷整個數組來查找重覆元素。因此,這種方法在處理大型數組時可能會導致性能問題。⚠️

註:無法判斷{}NaN重覆的情況

const _deleteRepeat = array=>  {
    let len = array.length;
    // 排序後更加方便去重
    array = array.sort();
    const loop = index => {
        if (index >= 1) {
            if (array[index] === array[index - 1]) {
                array.splice(index, 1);
            }
            // 遞歸loop,然後數組去重
            loop(index - 1);
        }
    }
    loop(len - 1);
    return array;
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, NaN, NaN, {}, {}, "abc", false, null, true, undefined ]

利用Map數據結構去重

創建⼀個空 Map 數據結構, 遍歷需要去重的數組, 把數組的每⼀個元素作為 key 存到 Map 中。由於 Map 中不會出現相同的 key 值,所以最終得到的就是去重後的結果

時間複雜度為 O(n),因為只需要對所有元素進行一次遍歷和查找操作。因此,這種方法在處理大型數組時具有較好的性能。

註:無法判斷{} 重覆的情況

const _deleteRepeat = array => {
    let newArray = [];
    let map = new Map();
    array.forEach(item => {
        if (!map.has(item)) {
            map.set(item, true);
            newArray.push(item);
        }
    });
    return newArray
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

利用 reduce+includes 去重

reduce() 方法遍歷原數組

對於每個元素 item,我們使用 includes() 方法來檢查該元素是否已經存在於累加器數組 accumulator 中。如果不存在,則使用 push() 方法將該元素添加到累加器數組中。最後,我們返回累加器數組作為去重後的新數組。

時間複雜度為 O(n^2),因為需要對所有元素進行比較和查找操作。因此,這種方法在處理大型數組時可能會導致性能問題。⚠️

註:無法判斷{} 重覆的情況

const _deleteRepeat = array => {
    return array.reduce((accumulator, item) => {
        if (!accumulator.includes(item)) {
            accumulator.push(item);
        }
        return accumulator;
    }, []);
};
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

[...new Set(arr)]

利用擴展運算符 ...Set 對象去重數組

時間複雜度為 O(n),Set 對象只需要遍歷一次原數組即可完成去重操作

註:無法判斷{}重覆的情況

const _deleteRepeat = array => {
    return [...new Set(array)];
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # 1. Java語言概述 ## 1.1 Java概述 - 是`SUN`(`Stanford University Network`,斯坦福大學網路公司)1995年推出的一門高級編程語言。 - 是一種`面向Internet`的編程語言。Java一開始富有吸引力是因為Java程式可以在Web瀏覽器中運 ...
  • ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 本篇概覽 - 本文是《quarkus實戰》系列的第二篇 ...
  • ## 模擬ArrayLIst的底層實現 ```java package com.tedu.api04.list; import java.util.Objects; /** * @author LIGENSEN * Date: 2023/7/20 11:35 */ public class Arra ...
  • # Unity UGUI的RectMask2D(2D遮罩)組件的介紹及使用 ## 1. 什麼是RectMask2D組件? RectMask2D是Unity UGUI中的一個組件,用於實現2D遮罩效果。它可以限制子對象在指定的矩形區域內顯示,超出區域的部分將被遮罩隱藏。 ## 2. RectMask2 ...
  • # Unity UGUI的LayoutElement(佈局元素)組件的介紹及使用 ## 1. 什麼是LayoutElement組件? LayoutElement是Unity UGUI中的一個佈局元素組件,用於控制UI元素在佈局中的大小和位置。它可以用於自動調整UI元素的大小,以適應不同的屏幕解析度和 ...
  • # shell腳本-入侵檢測與告警 ## 原理 利用inotifywait命令對一些重要的目錄作一個實施監控,例如:當/root 、/usr/bin 等目錄發生改變的,利用inotifywait看可以對其作一個監控作用。 ## inotifywait ### 介紹 inotifywait 是一個 L ...
  • 首先來看一下需要操作的函數,以及配置的步驟: 圖1 圖2 Code: usart.c #include "usart.h"void ustart_Init(void ){ GPIO_InitTypeDef GPIO_Init_Ustar ; // 定義輸出埠TX的結構體對象 USART_InitT ...
  • ## 一、mysql安裝 在配置Hive之前一般都需要安裝和配置MySQL,因為Hive為了能操作HDFS上的數據集,那麼他需要知道數據的切分格式,如行列分隔符,存儲類型,是否壓縮,數據的存儲地址等信息。 為了方便以後操作所以他需要將這些信息通過一張表存儲起來,然後將這張表(元數據)存儲到mysql ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...