javascript之數組去重

雙重循環

  • 雙重循環是利用兩個for循環來實現數組去重的,兼容性最好,可是若是數組的數據過於龐大的時候,性能不佳。
function unique(array) {
    let result = []
    for(var i = 0; i < array.length; i++){
        for(var j = 0; j < result.length; j ++){
            if (array[i] === result[j]) {
                // 若是result中有和array[i]相同的項,直接跳出循環再也不繼續,而且j不會自增
                // j 不自增,就意味着,j不會等於result.length,下面的if語句就不會執行
                break
            }
        }
        // 若是result中沒有與array[i]相同的項,那麼第二層for循環完畢以後,j === result.length
        // 並將這輪循環的 array[i] push 到result中
        if (j === result.length) {
            result.push(array[i])
        }
    }
    return result
}
複製代碼

使用indexOf()方法

  • 經過indexOf()方法,來判斷數組中是否存在指定的值,找到以後返回下標,沒有找到則返回 -1
function unique(array) {
    var res = []
    for (var i = 0; i < array.length; i ++){
        if (res.indexOf(array[i]) === -1) {
            res.push(array[i])
        }
    }
    return res
}
複製代碼

ES5的filter()方法結合indexOf()方法去重

  • filter()方法能夠過濾數組,返回過濾後的數組,且不改變原數組
function unique(array) {
    return array.filter((item, index, self) => self.indexOf(item) === index)
    // [1,1,1,1].indexOf(1)返回的是第一個'1'的下標0,不會再查詢第一個 '1' 後面的元素了。
    // 在這裏,self.indexOf(item)每次返回的都是下標0,除了第一個元素(index = 0),以後等式都不成立了。
}
複製代碼

經過對象的key-value來實現去重

  • 對象有個hasOwnProperty()方法,用來查找對象是否含有某個key,返回布爾值
  • 注意,若是咱們定義一個以下的對象,結果會是什麼呢 ?
var obj = {
    1: 'number1',
    '1': 'string1'
}
複製代碼
  • 答案是字符串'1'會將數字1覆蓋,知道這個小細節以後,咱們再來實現去重的方法。
function unique(array) {
    var obj = {}
    return array.filter((item, index, self) => {
        // 若是對象中沒有找到 typeof item + item, 則向其添加一個 key: typeof item + item,value設置爲true,表示將item過濾出來。
        // value能夠隨便設置,除了0,'',undefined等等這些會轉化成false值的值
        return obj.hasOwnProperty(typeof item + item) ? false : obj[typeof item + item] = true
    })
}
複製代碼

最後咱們能夠採用ES6中的一種新的數據結果Set,它相似於數組,可是它的項都是惟一的,沒有重複的值。

Set自己是一個構造函數,用來生成 Set 數據結構。

  1. Set 結構的實例有如下屬性。數組

    • Set.prototype.constructor:構造函數,默認就是Set函數。
    • Set.prototype.size:返回Set實例的成員總數。
  2. Set 實例的方法分爲兩大類:操做方法(用於操做數據)和遍歷方法(用於遍歷成員)。bash

    • add(value):添加某個值,返回 Set 結構自己。
    • delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
    • has(value):返回一個布爾值,表示該值是否爲Set的成員。
    • clear():清除全部成員,沒有返回值。
    • keys():返回鍵名的遍歷器
    • values():返回鍵值的遍歷器
    • entries():返回鍵值對的遍歷器
    • forEach():使用回調函數遍歷每一個成員
var uniqueArr = new Set([1,2,3,1,'1','a','a'])

>>>uniqueArr
<<< Set(5) {1, 2, 3, "1", "a"}

>>> uniqueArr instanceof Array
<<< false
複製代碼
  • 能夠看到,返回的結果是Set數據結果,那麼如何返回一個數組呢?這就要用到ES6提供的另外一個數組方法了
  • Array.from(obj, fn, context)方法將一個類數組對象或者可遍歷對象轉換成一個真正的數組,它能夠接受三個參數,第一個是須要轉化的對象,第二個是一個函數,對象的每一項都會執行這個函數,返回處理後的項,context指定執行fn的this對象

理解用法以後,咱們再來看一下如何使用Set來實現數組去重

function unique(array) {
    return Array.from(new Set(array))
}
複製代碼

固然也能夠不使用Array.from()方法,使用ES6 '...' 擴展運算符

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

// 咱們能夠簡化一下這個函數

var unique = (array) => [...new Set(array)]
複製代碼

總結:咱們看到,數組去重的方式有不少,但以上都是在處理基本數據類型,可是若是碰到數組中存在對象的時候,還須要另當別論。看下以下的例子:

>>> NaN === NaN
<<< false

>>> NaN == NaN
<<< false

>>> {} == {}
<<< false

>>> {} === {}
<<< false

>>> undefined == undefined
<<< true

>>> undefined === undefined
<<< true

>>> null == null
<<< true

>>> null === null
<<< true
複製代碼
相關文章
相關標籤/搜索