無論是在面試還是在項目開發中,數組去重是經常碰到的問題。今天老K為大家總結一下幾種好用的數組去重的方法。
ES5的方法:
一、利用兩次for循環,然后splice去重(ES5中最常用)
function unique(arr){ if(toString.call(arr) !== "[object Array]"){ console.log('必須為數組'); return ; } for(var i=0; i<arr.length; i++){ for(var j = i+1; j<arr.length; j++){ if(arr[i] === arr[j]){ //第一個等同于第二個,splice方法刪除第二個 arr.splice(j,1); j--; } } } return arr; }; var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr); // [2, "a", true, "true", false, "false", undefined, null, NaN, NaN, "NaN", 0, {…}, {…}]
原理:雙層循環,外層循環元素,內層循環時比較值。值相同時,則刪去這個值。
優點:兼容強。
缺點:不能去重NaN,object對象,數據量大時,效率不高。
二、利用數組的排序方法sort去重
function unique(arr){ if (toString.call(arr) !== "[object Array]"){ console.log('必須為數組'); return; } arr = arr.sort() var new_array = [arr[0]]; for(var i =1; i<arr.length; i++){ if(arr[i] !== arr[i-1]){ new_array.push(arr[i]); } } return new_array; }; var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr);//[0, 2, NaN, NaN, "NaN", {…}, {…}, "a", false, "false", null, true, "true", undefined]
原理:利用sort()排序方法,然后根據排序后的結果進行遍歷及相鄰元素比對。
優點:兼容強,邏輯簡單,容易理解。
缺點:不能去重NaN,object對象。
三、利用對象的屬性不能相同的特點進行去重,主要用hasOwnProperty
function unique(arr){ if (toString.call(arr) !== "[object Array]"){ console.log('必須為數組'); return; } var obj = {}; var new_arr = []; for(var i = 0; i< arr.length; i++){ if(!obj.hasOwnProperty(typeof arr[i]+arr[i])){ new_arr.push(arr[i]); obj[typeof arr[i]+arr[i]] = true; } } return new_arr } var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {…}]
原理:新建個空對象,空數組,遍歷目標數組。如果元素不是對象的鍵,將元素加到新數組里,同時給鍵賦值。如果已是對象的鍵,則忽略。利用typeof 區分布爾值和”true”、“false“,NaN和“NaN“。
優點:可以將各種類型的數據去重。
缺點:暫無。
ES6的方法:
一、 利用 ES6的Set對象的特性去重
function unique(arr){ if(!Array.isArray(arr)){ console.log('必須為數組'); return; } return Array.from(new Set(arr)) //或者用擴展運算符轉化為數組 return [...new Set(arr)] }; var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr); // [2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {...},{...}]
原理:利用ES6的Set對象自動排除重復項的特性,通過ES6的Array的from方法或者擴展運算符將Set對象轉化為數組。
優點:不考慮兼容性,這種方法代碼最少。
缺點:這種方法無法去重object對象,需要考慮兼容問題。
二、利用ES6的數組方法indexOf去重
function unique(arr){ if(!Array.isArray(arr)){ console.log('必須為數組'); return; } var new_array = []; for(var i = 0; i< arr.length; i++){ if (new_array.indexOf(arr[i]) === -1){ new_array.push(arr[i]) } } return new_array; }; var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, NaN, "NaN", 0, {…}, {…}]
原理:新建一個空的結果數組,for 循環原數組,利用indexOf方法判斷結果數組是否存在當前元素,如果有相同的值則跳過,不相同則push進數組。
優點:利用ES6數組的新方法,邏輯簡單,容易理解。
缺點:不能去重NaN,object對象,需要考慮兼容問題。
三、利用ES6的數組方法includes去重
function unique(arr){ if(!Array.isArray(arr)){ console.log('必須為數組'); return; } var new_array = []; for(var i = 0; i< arr.length; i++){ if ( !new_array.includes(arr[i]) ){ new_array.push(arr[i]) } } return new_array; }; var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {…}, {…}]
原理:創建個新的空數組new_array,遍歷目標數組,利用includes方法判斷目標數組的元素是否在新數組里,如果沒有,將元素添加到新數組中,如果有則忽略。
優點:利用ES6數組的新方法,邏輯簡單,容易理解。
缺點:不能去重object對象,需要考慮兼容性。
四、利用ES6的filter和indexOf去重
function unique(arr){ if(!Array.isArray(arr)){ console.log('必須為數組'); return; } return arr.filter(function(item, index, arr){ return arr.indexOf(item, 0) === index; }); } var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr); //[2, "a", true, "true", false, "false", undefined, null, "NaN", 0, {…}, {…}]
原理:給filter一個過濾條件,獲取元素在原始數組的第一個索引,如果等于當前索引值,返回當前元素。
優點:利用ES6數組的新方法,邏輯簡單,容易理解。
缺點:不能去重object對象和NaN,需要考慮兼容性。
五、利用ES6的Map數據格式去重
function unique(arr){ if(!Array.isArray(arr)){ console.log('必須為數組'); return; } let map = new Map(); let new_array = new Array(); for(let i = 0; i<arr.length; i++){ if(map.has(arr[i])){ map.set(arr[i], true); }else{ map.set(arr[i], false); new_array.push(arr[i]); } } return new_array; } var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {…}, {…}]
原理:創建一個新數組,遍歷目標數組,如果元素沒有在Map里,則添加到新數組。
優點:利用ES6數組的新數據結構,邏輯簡單,容易理解。
缺點:不能去重object對象,需要考慮兼容性。
六、利用ES6的reduce和includes去重
function unique(arr){ if(!Array.isArray(arr)){ console.log('必須為數組'); return; } return arr.reduce( (prev, cur) => prev.includes(cur) ? prev : [...prev,cur], []); } var arr = [2,2,'a','a',true,true,'true','true',false,false,'false','false',undefined,undefined,null,null,NaN,NaN,'NaN',0,0,{},{}]; unique(arr); //[2, "a", true, "true", false, "false", undefined, null, NaN, "NaN", 0, {…}, {…}]
原理:創建一個新數組,遍歷目標數組,如果元素沒有在Map里,則添加到新數組。
優點:利用ES6數組的reduce,設置初始值為一個空數組,迭代判斷當前元素是否在上一個數組中,如果有則返回上一個數組,沒有則把當前元素添加到上一個元素中然后返回一個新數組。
缺點:不能去重object對象,需要考慮兼容性。
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。