看起來不那麼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; }