利用ES6 Set集合成員具備惟一值的特性,再借助Array.from將類數組轉爲真正的數組
咱們能夠很簡單的完成數組去重任務數組
let res = Array.from(new Set(arr));
indexOf():
返回數組中某個指定的元素第一次出現的位置(索引)。若是在數組中沒找到指定元素則返回 -1。
filter():
返回指定數組中符合條件的全部元素
關鍵語句:this
index === array.indexOf(ele)
咱們利用indexOf獲得的下標與當前元素的下標來判斷這個元素是不是第一次出現,而後在利用filter的過濾特性便可。
這裏須要注意的判斷NaN,由於 NaN !== NaN,因此indexOf(NaN)始終返回-1,因此咱們須要額外去判斷prototype
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,代表已經存在該元素code
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; }
在數組排序後,相同的數據會集中在一塊兒,所以只須要比較相鄰元素是否相等便可,
比較符能夠用 嚴格比較運算符(===) 或者 Object.is()
它們不一樣之處只有兩個:一是+0不等於-0,二是NaN等於自身。
因此對於NaN,若是使用===,則須要額外判斷
根據以下方案,數組最後一個元素必然是惟一值,因此在循環後把末尾的元素添加進去索引
Array.prototype.uniq = function(){ let res = []; let arr = this.sort(); for(let i = 0; i < arr.length-2; i++){ if(!Object.is(arr[i], arr[i+1])){ res.push(arr[i]) } } res.push(arr.pop()); return res; }