看起來不那麼low的JS數組去重方法

①利用ES6的Set集合

利用ES6 Set集合成員具有唯一值的特性,再借助Array.from將類數組轉爲真正的數組
我們可以很簡單的完成數組去重任務

let res = Array.from(new Set(arr));

②indexOf和filter的配合

indexOf():
返回數組中某個指定的元素第一次出現的位置(索引)。如果在數組中沒找到指定元素則返回 -1。
filter():
返回指定數組中符合條件的所有元素
關鍵語句:

index === array.indexOf(ele)

我們利用indexOf得到的下標與當前元素的下標來判斷這個元素是否是第一次出現,然後在利用filter的過濾特性即可。
這裏需要注意的判斷NaN,因爲 NaN !== NaN,所有indexOf(NaN)始終返回-1,所以我們需要額外去判斷

Array.prototype.uniq = function(){
    let flag = true;             // 定義標記用來判斷NaN
    return this.filter((ele, index, array) => {
        if(flag && ele!==ele){
            flag = false;
            return true;
        }
        return index===array.indexOf(ele)
    })
}

③利用對象的鍵

核心:利用對象的鍵來存儲我們的元素
如果沒有對象中沒有這個鍵,則進行存儲,並設置這個鍵對應值爲true,表明已經存在該元素

Array.prototype.uniq = function(){
    let hash = {};
    let data = [];
    this.forEach(ele => {
        if (!hash[ele])  {
            hash[ele] = true;
            data.push(ele);
        }    
    })
   return data;
}    

注意:由於普通對象的鍵都是字符串,所以對於像 Number(1)和String(1)則視爲它們是同一值,無法正確判斷,對於引用類型的數據也是如此( 如 {} 和 {} 視爲同一值)

解決辦法:在ES6中提供了Map集合,Map的鍵不再侷限於字符串,而是任意類型,可以說是一個完整的hash結構,利用Map替換普通對象{}則可以解決上面的問題

Array.prototype.uniq = function(){
    let map = new Map();
    let data = [];
    this.forEach(ele => {
        if(!map.get(ele)){
            map.set(ele, true);
            data.push(ele);
        }
    });
    return data;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章