1. 程式人生 > 其它 >JavaScript:陣列去重總結

JavaScript:陣列去重總結

陣列去重總結

1. 雙層迴圈

var array = [1, 1, '1', '1'];

function unique(array) {
    // res用來儲存結果
    var res = [];
    for (var i = 0, arrayLen = array.length; i < arrayLen; i++) {
        for (var j = 0, resLen = res.length; j < resLen; j++ ) {
            if (array[i] === res[j]) {
                break;
            }
        }
        // 如果array[i]是唯一的,那麼執行完迴圈,j等於resLen
        if (j === resLen) {
            res.push(array[i])
        }
    }
    return res;
}

console.log(unique(array)); // [1, "1"]

2.indexOf

var array = [1, 1, '1'];

function unique(array) {
    var res = [];
    for (var i = 0, len = array.length; i < len; i++) {
        var current = array[i];
        if (res.indexOf(current) === -1) {
            res.push(current)
        }
    }
    return res;
}

console.log(unique(array));

3.排序後去重

試想我們先將要去重的陣列使用 sort 方法排序後,相同的值就會被排在一起,然後我們就可以只判斷當前元素與上一個元素是否相同,相同就說明重複,不相同就新增進 res,讓我們寫個 demo:

var array = [1, 1, '1'];

function unique(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;
}

console.log(unique(array));

4.filter

var array = [1, 2, 1, 1, '1'];

function unique(array) {
    var res = array.filter(function(item, index, array){
        return array.indexOf(item) === index;
    })
    return res;
}

console.log(unique(array));

5.Object 鍵值對

這種方法是利用一個空的 Object 物件,我們把陣列的值存成 Object 的 key 值,比如 Object[value1] = true,在判斷另一個值的時候,如果 Object[value2]存在的話,就說明該值是重複的。示例程式碼如下:

var array = [1, 2, 1, 1, '1'];

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

console.log(unique(array)); // [1, 2]

我們可以發現,是有問題的,因為 1 和 '1' 是不同的,但是這種方法會判斷為同一個值,這是因為物件的鍵值只能是字串,所以我們可以使用 typeof item + item 拼成字串作為 key 值來避免這個問題:

var array = [1, 2, 1, 1, '1'];

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

console.log(unique(array)); // [1, 2, "1"]

然而,即便如此,我們依然無法正確區分出兩個物件,比如 {value: 1} 和 {value: 2},因為 typeof item + item 的結果都會是 object[object Object],不過我們可以使用 JSON.stringify 將物件序列化:

var array = [{value: 1}, {value: 1}, {value: 2}];

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

console.log(unique(array)); // [{value: 1}, {value: 2}]

6.ES6

隨著 ES6 的到來,去重的方法又有了進展,比如我們可以使用 Set 和 Map 資料結構,以 Set 為例,ES6 提供了新的資料結構 Set。它類似於陣列,但是成員的值都是唯一的,沒有重複的值。

1.Set 方法

var array = [1, 2, 1, 1, '1'];

function unique(array) {
   return Array.from(new Set(array));
}

console.log(unique(array)); // [1, 2, "1"]

甚至可以再簡化下:

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

還可以再簡化下:

var unique = (a) => [...new Set(a)]

2.Map 方法

function unique (arr) {
    const seen = new Map()
    return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
}

7.還有特殊型別的比較(這個一般用的比較少,甚至可以忽略)

直接放一個表:

總結

雖然去重的結果有所不同,但更重要的是讓我們知道在合適的場景要選擇合適的方法。、

參考文章:
JavaScript專題之陣列去重

作者:熊貓吃西瓜 出處:https://www.cnblogs.com/XF-eng 本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文連線,否則保留追究法律責任的權利。