記錄--數組去重的五種方法

来源:https://www.cnblogs.com/smileZAZ/archive/2023/02/13/17117229.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 您或許會疑惑,網上那麼多去重方法,這篇文章還有什麼意義? 彆著急,這篇文章只節選了簡單的,好玩的,古老的,有實際講解意義的去重方法,除了去重的實現以外,我還將和您分享這其中的其他細節和拓展。 您或許不理解,為什麼只有五種? 當然,我 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

前言

您或許會疑惑,網上那麼多去重方法,這篇文章還有什麼意義?

彆著急,這篇文章只節選了簡單的,好玩的,古老的,有實際講解意義的去重方法,除了去重的實現以外,我還將和您分享這其中的其他細節和拓展

您或許不理解,為什麼只有五種?

當然,我可以舉例出更多的例子來,但那有什麼意義呢?工作中用不到那麼多,會其中一二就可以。即使是面試,能說出五種也是完全足夠的。所以,我們完全沒有必要去記憶更多的去重方式。

五種方式

最簡單的方法,ES6的Set去重(最推薦)

這個方法是我日常開發中最喜歡用的方法,因為,他的使用方法是所有去重中最簡單的。而我是一個懶癌患者。

new Set是ES6新推出的一種類型。他和數組的區別在於,Set類型中的數據不可以有重覆的值。當然,數組的一些方法Set也無法調用。

使用方法:其實很簡單,將一個數組轉化為Set數據,再轉化回來,就完成了去重。

    const arr = [1,1,2,2,3,3,4,4,5,5];
    const setData = Array.from(new Set(arr));
    console.log(setData);

圖例↓

但是Set去重有一個弊端,他無法去重引用類型的數據。比如對象數組。

圖例:

所以如果您的數組中都是值類型的數據(比如全string或者全number),那麼使用Set進行去重一定是首選,會為您減少很多的麻煩。

最古老的方法,雙重for迴圈去重

在很早以前,還沒有Set,沒有map,filter的時候,雙重for迴圈幾乎是去重的唯一方式。

//雙重迴圈去重
const handleRemoveRepeat = (arr) => {
    for (let i=0,len = arr.length; i < len; i++) {
        for (let j = i + 1; j < len; j++) {
            if (arr[i] === arr[j]) {
                arr.splice(j, 1);
                j--;
                len--;
            }
        }
    }
    return arr;
};

圖例:

這裡有一個有意思的地方,或許您不太明白,為什麼我的for迴圈的初始表達式中聲明瞭兩個東西:let i = 0;len = arr.length;

我來給您解答:

被圈起來的三個表示的是for迴圈的三個表達式,依次分別是:初始表達式判斷表達式自增表達式。其中,初始表達式在for迴圈開始的時候會執行一次,以後就不會再執行了,但是判斷表達式自增表達式會在每一次迴圈的時候都去執行。

如果您不太理解文字表達,沒關係,我畫了張圖。

 

您或許已經發現,後一個圈中的內容會陷入一個迴圈。

但這和我們一開始len = arr.length有什麼關係呢?

值得註意的是,如果一開始定義,那麼每一次迴圈,都需要走 arr.length,length可是個方法,雖然他的消耗並不大,但在for迴圈中這個消耗會被方法,假設這個迴圈需要迴圈10000次呢,length就會被執行10000次。

最雞肋的去重方式,indexOf去重

indexOf還是相對簡單又雞肋。為什麼說他雞肋呢?說難吧,indexOf方法確實比上文的雙重for迴圈簡單。說簡單吧,嘿,他沒Set方法去重來的更簡單。所以雞肋。

//去重
const handleRemoveRepeat = (arr) => {
    let repeatArr = [];
    for (let i = 0,len = arr.length ; i < len; i++) 
     if (repeatArr.indexOf(arr[i]) === -1)  repeatArr.push(arr[i])
    return repeatArr;
}

 圖例:

同樣的,這個方法也有一個細節點,您或許已經發現了,上文的if和for沒有花括弧;是的;for和if都預設對下麵一條語句負責。在沒有必要的情況下,不用多加一個{}。

或許您會覺得這不可讀,這就是有意思的地方了,這是一個工具類方法,註定被藏在utils中的一個方法,他無關業務邏輯,並不需要有太大可讀性。

而且,這麼寫還有一個很原因:給人的視覺衝擊會比較大。說點人話就是 -----很裝逼;

一種類似於indexOf的去重方法,includes去重

使用includes的去重方法和indexOf不能說很像,基本上一模一樣。變換的僅僅只是判斷方法。

includes的判斷方法更簡單了。迴圈數組的每一樣,用新數組檢測當前數組中是否包含數組項,如果不包含,則追加該元素

const handleRemoveRepeat = (arr) => {
    let repeatArr = [];
    for (let i = 0,len = arr.length ; i < len; i++)
        if (!repeatArr.includes(arr[i])) repeatArr.push(arr[i])
    return repeatArr;
}

圖例

includes方法在除了去重以外的場景,還是很好用的。

最有趣的去重方法,使用filter去重。

使用filter配合indexOf進行的去重過程,真的可以非常的簡單且富含趣味性。

//去重
const handleRemoveRepeat = (arr) => arr.filter((item,index) => arr.indexOf(item,0) === index);

是的,沒了,就一行。

圖例

您是否沒有反應過來?乍一看,不知道他是怎麼完成去重的。

小問題,我為您解答疑惑。

indexOf的特性是返回被查找的目標中包含的第一個位置的索引

如圖,下標為0和下標為4的位置存儲的都是“1”。但是indexOf()只返回了0。因為indexOf的特性是返回被查找的目標中包含的第一個位置的索引。

同樣的,我們可以利用這個特性。來完成去重,文字描述恐怕很難表達準確,您可以看看下麵的這張圖。

 

您或許會問:如果要去重對象數組怎麼辦?

去除對象數組的方式他並不是很穩定,這不像我們去重值類型數據的數組,上面的五種方法隨便複製一種,往裡面一調用就好了。絕對不會出問題。

但是對象數組去重,需要有一個去重條件,也就是根據哪個欄位進行去重。

用雙重迴圈去重舉個例子:

 圖例

如上圖,我們就是拿數據的id作為去重條件的。

像這樣的對象數組就不能直接提供方法,因為每一個場景下的對象數組都不一定一樣。我這是根據id去重,萬一其他地方需要根據其他欄位去重呢。

所以,如果您需要去重對象,根據上方的截圖中的代碼。使用雙重for迴圈的方法,自己自定義一個可以滿足您當前業務需求的去重方法。

本文轉載於:

https://juejin.cn/post/7152759573978284040

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


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

-Advertisement-
Play Games
更多相關文章
  • 摘要:提供一種執行高效的TereData的marco遷移方案。 本文分享自華為雲社區《GaussDB(DWS)遷移 - teredata相容 -- macro相容 # 【玩轉PB級數倉GaussDB(DWS)】》,作者: 譡里個檔 。 Teradata的巨集是一組可以接受參數的SQL語句,通過調用巨集名 ...
  • 總結了一下在以往工作中,對於`Hive SQL`調優的一些實際應用,是日常積累的一些優化技巧,如有出入,歡迎在評論區留言探討~ ...
  • 記錄一些工作中有意思的統計指標,做過一些簡化方便大家閱讀,記錄如有錯誤,歡迎在評論區提問討論~ 問題類型 連續問題 兩種思路 第一種:日期減去一列數字得出日期相同,主要是通過row_number視窗函數 第二種:後一個日期減去前一個日期差值相等,用的較少,可以用lag/lead視窗函數解決 分組問題 ...
  • 一、研發背景 DataX官方開源的版本支持HDFS文件的讀寫,但是截止目前,並沒有支持Parquet文件的讀寫,得益於DataX出色的數據同步性能,去年公司的項目大部分採用了DataX作為數據同步工具,但是從CDH集群同步Parquet或者將其他數據源的數據以Parquet格式寫入HDFS,這兩個常 ...
  • 前文回顧 實現一個簡單的Database系列 譯註:cstack在github維護了一個簡單的、類似sqlite的資料庫實現,通過這個簡單的項目,可以很好的理解資料庫是如何運行的。本文是第八篇,主要是對B-tree的葉子節點格式的實現 Part 8 B-Tree葉子節點格式 我們準備把表的格式從非排 ...
  • Postgresql通過docker進行高可用部署 在postgresql官網看了pgpool-II的文檔,發現部署比較麻煩 pgpool-II官方文檔:https://www.pgpool.net/mediawiki/index.php/Documentation 為了方便快捷還是使用docker ...
  • 2022年12月22日工業和信息化部令第57號公佈,自2023年7月1日起施行 主要總結為以下幾點: 1.型號核准證的有效期不短於2年,不超過5年,型號核准證每次延續的有效期不超過5年 2.微功率短距離無線電發射設備使用說明中應當註明“使用微功率短距離無線電發射設備應當符合國家無線電管理有關規定”字 ...
  • html基礎入門 1. 什麼是html Hypertext Markup Language 超文本標記語言 2. 基本結構 <!DOCTYPE html> <!-- 註釋:此為html5的聲明方式 --> <html> <head></head> <body></body> </html> 順序 聲 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...