整理數組去重的幾種常用方法

来源:https://www.cnblogs.com/ImmortalWang/archive/2019/03/13/10522651.html
-Advertisement-
Play Games

最近面試有一個面試題,要求儘可能多的列舉數組去重的方法,現整理一下 1、最簡單的去重方法 2、排序後相鄰去除法 該方法存在一個問題,當數組中存在number類型的2,和string類型的‘2’時,因sort方法會調用每個數組項的toString()方法,得到字元串,然後再對得到的字元串進行排序。如對 ...


最近面試有一個面試題,要求儘可能多的列舉數組去重的方法,現整理一下

1、最簡單的去重方法

// 最簡單數組去重法
/*
* 新建一新數組,遍歷傳入數組,值不在新數組就push進該新數組中
* IE8以下不支持數組的indexOf方法
* */
function uniq(array){
    var temp = []; //一個新的臨時數組
    for(var i = 0; i < array.length; i++){
        if(temp.indexOf(array[i]) == -1){
            temp.push(array[i]);
        }
    }
    return temp;
}

var aa = [1,2,2,4,9,6,7,5,2,3,5,6,5];
console.log(uniq(aa));

2、排序後相鄰去除法

/*
* 給傳入數組排序,排序後相同值相鄰,
* 然後遍歷時,新數組只加入不與前一值重覆的值。
* 會打亂原來數組的順序
* */
function uniq(array){
    array.sort();
    var temp=[array[0]];
    for(var i = 1; i < array.length; i++){
        if( array[i] !== temp[temp.length-1]){
            temp.push(array[i]);
        }
    }
    return temp;
}

var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));//[1, 2, "2", 2, 3, 4, 5, 6, 9, "a"]

該方法存在一個問題,當數組中存在number類型的2,和string類型的‘2’時,因sort方法會調用每個數組項的toString()方法,得到字元串,然後再對得到的字元串進行排序。如對數組[15,3]調用sort()方法,得到的結果還是[15,3]雖然數值15比3大,但在進行字元串比較時”15”則排在”3”前面,所有最後的結果就會出現上面列印出的問題。對sort()方法添加比較函數即可解決,這裡暫不詳細說明。

3、對象鍵值法去重

/*
* 速度最快, 占空間最多(空間換時間)
*
* 該方法執行的速度比其他任何方法都快, 就是占用的記憶體大一些。
* 現思路:新建一js對象以及新數組,遍歷傳入數組時,判斷值是否為js對象的鍵,
* 不是的話給對象新增該鍵並放入新數組。
* 註意點:判斷是否為js對象鍵時,會自動對傳入的鍵執行“toString()”,
* 不同的鍵可能會被誤認為一樣,例如n[val]-- n[1]、n["1"];
* 解決上述問題還是得調用“indexOf”。*/
function uniq(array){
    var temp = {}, r = [], len = array.length, val, type;
    for (var i = 0; i < len; i++) {
        val = array[i];
        type = typeof val;
        if (!temp[val]) {
            temp[val] = [type];
            r.push(val);
        } else if (temp[val].indexOf(type) < 0) {
            temp[val].push(type);
            r.push(val);
        }
    }
    return r;
}

var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));

判斷是否為js對象鍵時,會自動對傳入的鍵執行“toString()“,如果不判斷數據類型,結果就不會同時存在 2和”2“

4、數組下標法

/*
*
* 還是得調用“indexOf”性能跟方法1差不多,
* 實現思路:如果當前數組的第i項在當前數組中第一次出現的位置不是i,
* 那麼表示第i項是重覆的,忽略掉。否則存入結果數組。
* */
function uniq(array){
    var temp = [];
    for(var i = 0; i < array.length; i++) {
        //如果當前數組的第i項在當前數組中第一次出現的位置是i,才存入數組;否則代表是重覆的
        if(array.indexOf(array[i]) == i){
            temp.push(array[i])
        }
    }
    return temp;
}

var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));

5、優化遍曆數組法

// 思路:獲取沒重覆的最右一值放入新數組
/*
* 推薦的方法
*
* 方法的實現代碼相當酷炫,
* 實現思路:獲取沒重覆的最右一值放入新數組。
* (檢測到有重覆值時終止當前迴圈同時進入頂層迴圈的下一輪判斷)*/
function uniq(array){
    var temp = [];
    var index = [];
    var l = array.length;
    for(var i = 0; i < l; i++) {
        for(var j = i + 1; j < l; j++){
            if (array[i] === array[j]){
                i++;
                j = i;
            }
        }
        temp.push(array[i]);
        index.push(i);
    }
    console.log(index);
    return temp;
}

var aa = [1,2,'2',2,3,5,'3',3,'2',6,5];
console.log(uniq(aa));

6、利用indexOf以及forEach

function uniq(arr){
    var temp = [],
    len = arr.length;
    arr.forEach(function(v, i ,arr){  //這裡利用map,filter方法也可以實現
        var bool = arr.indexOf(v,i+1);  //從傳入參數的下一個索引值開始尋找是否存在重覆
        if(bool === -1){
            temp.push(v);
        }
    })
    return temp;
};
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));


7、利用ES6的set

// 利用Array.from將Set結構轉換成數組
function uniq(arr){
    return Array.from(new Set(arr))
}
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5]
console.log(uniq(aa)) 
//拓展運算符(...)內部使用for...of迴圈
let arr = [1,2,"2",4,9,"a","a",2,3,5,6,5,7,8];
let newArr = [...new Set(arr)]; 
console.log(newArr); 

es6 大法好啊,誰用誰知道啊!!

註意。。。IE不支持!IE不支持!IE不支持!

 


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

-Advertisement-
Play Games
更多相關文章
  • 我們所看到的網頁,是一個有一個標簽搭建而成,就像蓋房子, 有地基(Ps.<html></html>): html標簽包裹所有的HTML代碼,不管是頁面搭建的body,還是連接樣式的head,統統都在。 有工程師(Ps.<head></head>): head標簽用於連接各種各樣的樣式,有CSS層疊樣 ...
  • 一、基本結構<!DOCTYPE html> //設置字元編碼集格式<html> //<head> //網頁頭部 <title></title></head><body> </body></html> 二、文本標記1.加粗 b2.傾斜 i3.下劃線 u4.刪除線 u5.上標 sup6.下標 sub三、 ...
  • 兩年一度的上海市星光計劃比賽被譽為職業技能大賽的奧林匹克,比賽分為中職組和高職組 隨著若幹年的發展,比賽的題目強度逐年提高,逐步向世界職業技能大賽的比賽強度靠攏 這次翻譯的題目是上海市第八屆星光計劃(2019年)技能大賽網站設計(中職教師組)的決賽題目。全文是英文的,學生組的題目和教師組差不多,個別 ...
  • 學習一門語言我們需要熟悉他的語法辭彙還有常用表達,同樣這種學習方法適用於學習任何一門技術,正則的入門很簡單例如我們想讓用戶輸入的數據只能是數字那麼我們可以用"^[0-9]*$"來實現對輸入數據的監控當然具體功能還涉及更多的知識層面,本文僅介紹正則表達式的入門哦😉 什麼是正則表達式? 我們來百度一下 ...
  • //首頁var zh_index = { "index1":"首頁", "index2":"產品實例" };var en_index = { "index1":"index", "index2":"Product examples" }; //服務支持var zh_serviceSupport = ...
  • ``` Title Hello Python 我的信息 註銷 klvchenklvchenklvchen klvchenklvc... ...
  • ``` Title 1000 ``` ...
  • chapter07 函數的擴展 7.1 函數預設值 7.1.1 參數預設值簡介 傳統做法的弊端(||):如果傳入的參數相等於(==)false的話,仍會被設為預設值,需要多加入一個if判斷,比較麻煩。 參數變數是預設聲明的,不可在函數體內部重覆聲明。 參數的預設值會在每次調用的時候重新計算 7.1. ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...