1. 程式人生 > 程式設計 >JS陣列去重詳情

JS陣列去重詳情

目錄
  • 1 測試用例
  • 2 陣列去重4大型別
    • 2.1 元素比較型
      • 2.1.1 雙層 for 迴圈逐一比較(es5常用)
      • 2.1.2 排序相鄰比較
    • 2.2 查詢元素位置型
      • 2.2.1 indexOf
      • 2.2.2 findIndex
    • 2.3 元素是否存在型
      • 2.3.1 includes
      • 2.3.2 some
    • 2.4 依託資料結構特性
      • 2.4.1 Map
      • 2.4.2 Set(ES6 最常用)
  • 3 補充

    1 測試用例

    // 測試用例
    const a = {};
    const b = { c: 1 };
    const array = [
      1,1,"1",{},{ c: 1 },{ c: 1},a,b,[],[1],undefined,null,NaN,];
    
    

    2 JS 陣列去重4大型別

    2.1 元素比較型

    此型別通過陣列元素之間進行比較來去重

    2.1.1 雙層 for 迴圈逐一比較(es5常用)

    使用雙層for迴圈逐一比較陣列元素,用splice方法去除重複的元素

    // 雙層for迴圈
    function uniq1(arr) {
        for (let i = 0; i < arr.length; i++) {
            for (let j = i + 1; j < arr.length; j++) {
                if (arr[i] === arr[j]) {
                    arr.splice(j,1)
                    j--
                }
            }
        }
        return arr
    }
    
    // 去重結果
    // [1,'1',{c:1},NaN]
    

    通過對比去重前後結果,重複的NaN沒有去掉,因為NaN === NaNfalse

    2.1.2 排序相鄰比較

    使用sort()方法對陣列元素進行排序,然後比較相鄰元素,用splice方法去除重複的元素。

    function uni2(arr) {
        arr.sort();
        for (let i = 0; i < arr.length - 1; i++) {
            arr[i] === arr[i + 1] && arr.splice(i + 1,1) && i--;
        }
        return arr;
    }
    
    
    

    也可以建立新陣列,將不重複的元素放入新陣列中

    function uniq3(arr) {
        arr = arr.sort()
        const newArr = [arr[0]]
        for (let i = 1; i < arr.length; i++) {
            if (arr[i] !== arr[i - 1]) {
                newArr.push(arr[i])
            }
        }
        return newArr
    }
    
    // 去重結果
    // [[],undefined]
    

    重複的NaN沒有去掉,因為NaN === NaN為false
    sort
    預設排序順序是將元素轉換為字串,物件轉換為字串都是[object Object] ,所以sort方法不能對陣列中的物件進行排序,也就有可能無法去除重複的物件,除非重複的物件本就相鄰

    2.2 查詢元素位置型

    此型別通過查詢元素第一次出現的位置來去重

    2.2.1 indexOf

    通過indexOf查詢當前元素第一次出現的位置是否為當前位置,若是,則放入新陣列

    function uniq4(arr) {
        let res = []
        for (let i = 0; i < arr.length; i++) {
            if (arr.indexOf(arr[i]) === i) {
                res.push(arr[i])
            }
        }
        return res
    }
    
    // 去重結果
    // [1,null]
    

    同樣,因為NaN === NaNfalse,所以用indexOf查詢NaN結果總是-1,從而在新陣列中不會有NaN

    2.2.2 findIndex

    通過findIndex查詢當前元素第一www.cppcns.com次出現的位置是否為當前位置,若是,則放入新陣列

    function uniq5(arr) {
        let res = []
        for (let i = 0; i < arr.length; i++) {
            if (arr.findIndex(item => item === arr[i]) === i) {
                res.push(arr[i])
            }
        }
        return res
    }
    // 去重結果
    // [1,null]
    
    
    

    同樣,因為NaN === NaNfalse,所以用findIndex查詢NaN結果總是-1,從而在新陣列中不會有NaN

    2.3 元素是否存在型

    此型別通過判斷在新陣列中是否存在當前元素來去重

    2.3.1 includes

    includes方法用來判斷一個數組是否包含一個指定的值

    function uniq6(arr) {
        let res = []
        for (let i = 0; i < arr.length; i++) {
            if (!res.includes(arr[i])) {
                res.push(arr[i])
            }
        }
        return res
    }
    // 去重結果
    // [1,NaN]
    
    
    

    includes使用零值相等演算法來確定是否找到給定的元素,所以可以判斷NaN是否在新陣列中存在

    2.3.2 some

    some方法用來測試陣列中是否至少有1個元素通過了被提供的函式測試

    function uniq7(arr) {
        let res = []
        fhttp://www.cppcns.comor (letwww.cppcns.com i = 0; i < arr.length; i++) {
            if (!res.some(item => item === arr[i])) {
                res.push(arr[i])
            }
        }
        return res
    }
    // 去重結果
    // [1,NaN]
    
    
    

    同樣,這裡仍舊使用了===來比較元素,因為NaN === NaNfalse,所以新陣列中會有多個NaN

    2.4 依託資料結構特性

    此型別通過ES6提供的資料結構MapSet本身不可重複特性來www.cppcns.com去重

    2.4.1 Map

    ES6提供的Map結構可以用各種型別的值(包括物件)當作鍵,且鍵是唯一的

    function uniq8(arr) {
        const map = new Map()
        for (let i = 0; i < arr.length; i++) {
            !map.has(arr[i]) && map.set(arr[i],true)
        }
        return [...map.keys()]
    }
    // 去重結果
    // [1,NaN]
    
    
    

    map.has方法對NaN也有效

    2.4.2 Set(ES6 最常用)

    Set結構的成員的值都是唯一的,沒有重複的值。

    function uniq9(arr) {
        return [...new Set(arr)]
    }
    
    // 去重結果
    // [1,NaN]
    
    

    3 補充

    上面所說的方法可以使用不同的Api進行改動,比如使用splice方法去除陣列元素的地方,我們可以通過filter方法來過濾陣列得到新陣列;

    再比如includes的方法中不用for迴圈遍歷陣列,通過reduce方法來代替等等。

    總之,方法有很多,但是萬變不離其宗

    有些去重方法對NaN無效,因為NaN === NaNfalse,如果有需求,可以使用Object.is(NaN,NaN)true來進行修改

    實際應用中,最常用的方法就是使用Set,也可以使用第三方庫lodash來處理

    到此這篇關於JS陣列去重詳情的文章就介紹到這了,更多相關JS陣列去重內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!