無論是在面試還是在項目開發中,數組去重是經常碰到的問題。今天老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對象,需要考慮兼容性。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/250421.html
微信掃一掃
支付寶掃一掃