Js數組去重的五種方式

一、利用雙層 for 循環

Talk is cheap,Show you the code.

var fruits=['蘋果','香蕉','葡萄','火龍果','蘋果','葡萄','火龍果']
distinct(fruits);
console.log(fruits);
//(4) ["蘋果", "香蕉", "葡萄", "火龍果"]
//雙重循環
function distinct(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);
                // splice 會改變數組長度,所以要將數組長度 len 和下標 j 減一
                len--;
                j--;
            }
        }
    }
    return arr;
}

這種方式的去重簡單來說就是我從第一個開始循環剩下的與之對比,去掉相同的所以這個的方式它的時間複雜度是O(n^2),如果數組長度很大,效率會很低,另外如果數組中有NAN的話也是無法去重的。(NaN==NaN爲false)

如果數組裏面是對象,我們知道每個對象都會開闢一個新的空間,所以在判斷相等時內容一樣,也不會一樣,所以在構造數據時,我們可以在裏面放一個唯一標識,一般後端給我媽傳回來的數據應該都有一個id。

    var student=[
        {
            id:1,
            name:'zs'
        },
        {
            id:2,
            name:'ls'
        },
        {
            id:3,
            name:'we'
        },
        {
            id:3,
            name:'we'
        },
        {
            id:1,
            name:'zs'
        },
    ]
distinct(student);
console.log(student);
// 0: {id: 1, name: "zs"}
// 1: {id: 2, name: "ls"}
// 2: {id: 3, name: "we"}
// length: 3
function distinct(arr) {
    for (let i=0, len=arr.length; i<len; i++) {
        for (let j=i+1; j<len; j++) {
            if (arr[i].id == arr[j].id) {
                arr.splice(j, 1);
                // splice 會改變數組長度,所以要將數組長度 len 和下標 j 減一
                len--;
                j--;
            }
        }
    }
    return arr;
}

二、利用數組方法

var fruits=['蘋果','香蕉','葡萄','火龍果','蘋果','葡萄','火龍果']
var fruits1Two=['蘋果','牛油果','桃子','菠蘿','桃子']
console.log(distinct(fruits,fruits1Two));
//(7) ["蘋果", "香蕉", "葡萄", "火龍果", "牛油果", "桃子", "菠蘿"]
//Array.filter() 加 indexOf
function distinct3(a, b) {
    let arr = a.concat(b);
    return arr.filter((item, index)=> {
        return arr.indexOf(item) === index
    })
}

利用indexOf檢測元素在數組中第一次出現的位置是否和元素現在的位置相等,如果不等則說明該元素是重複元素。此方法對象不去重,NaN會被忽落掉(arr.indexOf(Nan)=-1)。

三、利用排序

var fruits=['蘋果','香蕉','葡萄','火龍果','蘋果','葡萄','火龍果']
console.log(distinct(fruits));
// ["火龍果", "蘋果", "葡萄", "香蕉"]
function distinct(array) {
    var res = [];
    var sortedArray = array.concat().sort();
    var seen;
    for (var i = 0, len = sortedArray.length; i < len; i++) {
        // 如果是第一個元素或者相鄰的元素不相同
        if (!i || seen !== sortedArray[i]) {
            res.push(sortedArray[i])
        }
        seen = sortedArray[i];
    }
    return res;
}

先調用數組的排序方法,然後比較相鄰的兩個是否相等從而實現去重。此方法對象和NaN不去重,數字1與字符串1也不去重。
注:V8引擎 的 sort() 方法在數組長度小於等於10的情況下,會使用插入排序,大於10的情況下會使用快速排序

四、利用ES6中的Set方法

var fruits=['蘋果','香蕉','葡萄','火龍果','蘋果','葡萄','火龍果']
console.log(distinct(fruits));
// ["蘋果", "香蕉", "葡萄", "火龍果"]
function distinct(array) {
   return Array.from(new Set(array));
}

可以簡化爲:

function distinct(array) {
    return [...new Set(array)];
}

甚至:

let distinct = (a) => [...new Set(a)]

Es6提供的Set 結構的一個特性就是成員值都是唯一的,沒有重複的值,此方法對象不去重,NaN去重。

五、利用Object 鍵值對

function distinct(array) {
    var obj = {};
    return array.filter(function(item, index, array){
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
    })
}

這種方法是利用一個空的 Object 對象,我們把數組的值存成 Object 的 key 值,比如 Object[value1] = true,在判斷另一個值的時候,如果 Object[value2]存在的話,就說明該值是重複的,但是最後請注意這裏obj[typeof item + item] = true沒有直接使用obj[item],是因爲 123 和 ‘123’ 是不同的,直接使用前面的方法會判斷爲同一個值,因爲對象的鍵值只能是字符串,所以我們可以使用 typeof item + item 拼成字符串作爲 key 值來避免這個問題。此方法對象、NaN均去重。

參考:https://mp.weixin.qq.com/s/T_HZEqlUqqtufBPtg3eWvA

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章