最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript實現數組去重的14種方法大全

 更新時間:2025年03月12日 09:58:09   作者:儒雅的烤地瓜  
親愛的小伙伴,對于數組javascript中的數組去重方法你知道多少種呢?學會如何對數組進行去重對于javascript的學習來說也是十分重要的,下邊就讓我來分享一下我所知道的集中數組去重的方法吧,感興趣的小伙伴跟著小編一起來看看吧

一、利用for循環(huán)嵌套去重

var array = [ 0, 0, 1, 1, '1', '1', 'true', 'true', true, true, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 'a', 'a', {}, {}, { a: 1 }, { b: 2 }, { a: 1 }];
 
function unique(array) {
    // res用來存儲結果
    var res = [];
    for (var i = 0, arrayLen = array.length; i < arrayLen; i++) {
        for (var j = 0, resLen = res.length; j < resLen; j++ ) {
            if (array[i] === res[j]) {
                break;
            }
        }
        // 如果array[i]是唯一的,那么執(zhí)行完循環(huán),j等于resLen
        if (j === resLen) {
            res.push(array[i])
        }
    }
    return res;
}
// NaN 和 對象 無法去重
console.log(unique(array)); 
// [0, 1, '1', 'true', true, false, undefined, null, NaN, NaN, 'NaN', 'a', {…}, {…}, {…}, {…}, {…}]


輸出結果:NaN 和 對象 無法去重,其他都可以去重(包括null)

我的結論:for循環(huán) 判斷依據是全等===——值和類型都相同,才去重

二、利用splice() + for循環(huán)嵌套(ES5中最常用)

利用for循環(huán)嵌套,然后splice去重:將數組中的每一個元素依次與其他元素作比較,發(fā)現重復元素,刪除。

var arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
 
function unique(arr) {
  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;
}
 
console.log(arr[4],typeof arr[4],arr[6],typeof arr[6]) // true string true boolean
console.log(arr[4]==1,arr[6]==1) // false true
 
// NaN 和 {} 沒有去重,且兩個 null 直接消失了
// 如果第一個等同于第二個,splice方法刪除第二個,所以1跟'1'、true留1,false跟0留false
console.log(unique(arr)); // [1, 2, 'true', 15, false, undefined, NaN, NaN, 'NaN', 'a', {…}, {…}, {…}, {…}, {…}]

雙層循環(huán),外層循環(huán)元素,內層循環(huán)時比較值。值相同時,則刪去這個值。

輸出結果:NaN 和 對象 無法去重,且null會被忽略掉,直接消失了

我的結論:splice() 判斷依據是值等==——值相同

字符串類型的數字、boolean類型:true、false,比較時會轉為number類型的數字

三、利用indexOf() + for循環(huán)去重

indexOf() 方法可返回數組中某個指定的元素位置。
該方法將從頭到尾地檢索數組,看它是否含有對應的元素。開始檢索的位置在數組 start 處或數組的開頭(沒有指定 start 參數時)。如果找到一個 item,則返回 item 的第一次出現的位置。開始位置的索引為 0。
如果在數組中沒找到指定元素則返回 -1。
提示:如果你想查找字符串最后出現的位置,請使用 lastIndexOf() 方法。

新建一個空的結果數組,for 循環(huán)原數組,判斷結果數組是否存在當前元素,如果有相同的值則跳過,不相同則push進數組。

輸出結果:NaN 和 對象 無法去重,indexOf() 方法無法識別數組的 NaN 和 {} 成員。

我的結論:indexOf() 判斷依據是全等===——值和類型都相同,才去重

四、利用sort() + for循環(huán)去重

sort() 方法用于對數組的元素進行排序。

排序順序可以是字母或數字,并按升序或降序。

? 默認排序順序為按字母升序。

注意:當數字是按字母順序排列時"40"將排在"5"前面。

? 使用數字排序,你必須通過一個函數作為參數來調用。

函數指定數字是按照升序還是降序排列。

注意: 這種方法會改變原始數組!

利用sort()排序方法,然后根據排序后的結果進行遍歷及相鄰元素比對。 

var array = [1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
function unique(array) {
    if(!Array.isArray(array)) {
        console.log('type error');
        return;
    }
    arr = array.sort(); // 對array進行排序,sort()會改變原數組
    var arrys = [arr[0]]; // 新建一個數組,用于存放不包含重復元素的數組
    for(var i = 1; i < arr.length; i++) {
        if(arr[i] != arr[i-1]) {
            arrys.push(arr[i]);
        }
    }
    return arrys;
}
// NaN 和 對象 無法去重,其他都可以去重(包括null)
console.log(unique(array)); // [0, 1, 15, 2, NaN, NaN, 'NaN', {…}, {…}, {…}, {…}, {…}, 'a', false, null, 'true', true, undefined]

輸出結果:NaN 和 對象 無法去重,其他都可以去重(包括null)

我的結論:sort()  判斷依據是全等===——值和類型都相同,才去重

五、利用includes() + for循環(huán)去重(ES7)

includes() 方法用來判斷一個數組是否包含一個指定的值,如果是返回 true,否則false。

var arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
function unique(arr) {
  if (!Array.isArray(arr)) {
    console.log("type error!");
    return;
  }
 
  var array = [];
  for (var i = 0; i < arr.length; i++) {
    if (!array.includes(arr[i])) { // includes 檢測數組是否有某個值
      array.push(arr[i]);
    }
  }
  return array;
}
 
// 對象 無法去重,其他都可以去重(包括NaN、null)
console.log(unique(arr)); // [1, 2, '1', 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}, {…}, {…}, {…}]

輸出結果:對象 無法去重,其他都可以去重(包括NaN、null)

我的結論:includes() 判斷依據是全等===——值和類型都相同,才去重

PS:JavaScript String 對象也有 includes() 方法。

includes() 方法用于判斷字符串是否包含指定的子字符串。如果找到匹配的字符串則返回 true,否則返回 false。

注意:JavaScript String 對象的 includes() 方法區(qū)分大小寫。

六、利用Object鍵值對及其hasOwnProperty()去重

? hasOwnProperty方法

hasOwnProperty() 方法是 Object 的原型方法(也稱實例方法),它定義在 Object.prototype 對象之上,所有 Object 的實例對象都會繼承 hasOwnProperty() 方法。

hasOwnProperty() 方法用來檢測一個屬性是否是對象的自有屬性,而不是從原型鏈繼承的。如果該屬性是自有屬性,那么返回 true,否則返回 false。

換句話說,hasOwnProperty() 方法不會檢測對象的原型鏈,只會檢測當前對象本身,只有當前對象本身存在該屬性時才返回true。

用法:object.hasOwnProperty(propertyName)  ,參數propertyName指要檢測的屬性名;

? Object 鍵值對:var obj = {...}

—— 如何實現去重 ——

1、通過 filter 為數組的每一個元素做條件過濾。

2、再通過 三元運算 將數組的元素作為key登記在obj中,將它對應的值設為true。

3、通過 hasOwnProperty 判斷對象是否包含某一屬性(鍵),如果包含即返回false, filter 接收到false將會過濾掉該 item (array[index]) 的return事件。

Object 鍵值對這種方法是利用一個空的 Object 對象,我們把數組的值存成 Object 的 key 值,比如 Object[value1] = true,在判斷另一個值的時候,如果 Object[value2]存在的話,就說明該值是重復的。示例代碼如下:

var array = [1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
 
function unique(array) {
    var obj = {};
    return array.filter(function(item, index, array){
        return obj.hasOwnProperty(item) ? false : (obj[item] = true)
    })
}
// 可去重同值不同類型的項,但對象 無法去重,且原數組中除第一個對象外,所有對象都會被去(忽略)掉;
console.log(unique(array)); // [1, 2, 'true', 15, false, undefined, null, NaN, 0, 'a', {…}]


輸出結果:Object 鍵值對方法的有2個bug還會去重同值不同類型的項,且無法去重(區(qū)分)多個對象,即原數組中除第一個對象可以去重外,所有對象都會被去(忽略)掉,

缺點總結:

bug - 1 會去重同值不同類型的項

由于Object的鍵只能是String類型,因此 obj[1] 與 obj['1'] 以及 obj['true'] 與 obj[true]、obj[NaN] 與 obj['NaN'] 是等價的,它們引用同一個堆棧,最終在第二數組實參中 1 和 '1' 、'true' 和 true、NaN 和 'NaN' 被去重為同一個元素。

bug -2 原數組中除第一個對象可以去重外,所有對象都會被去(忽略)掉  ——無法去重多個對象

改進1.0:typeOf - 升級版

分析:我們可以發(fā)現,由于Object的鍵只能是String類型,這樣做是有問題的,因為 1 和 '1' 是不同的,但是這種方法會判斷為同一個值,這是因為對象的鍵值只能是字符串,所以我們可以通過使用 typeof item + item 的方式拼成一個字符串,來作為obj的 key 值來避免這個問題

var arr = [1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{}];
 
function unique(arr) {
  var obj = {};
  return arr.filter(function (item, index, arr) {
    // 使用typeof item+item拼成一個字符串,來作為 hasOwnProperty 的判斷依據以及obj的key值
    return obj.hasOwnProperty(typeof item + item)
      ? false
      : (obj[typeof item + item] = true);
  });
}
// 都可以去重,包括NaN、null、{}(僅限數組中的一個對象,如有其他對象都會被去掉)
console.log(unique(arr)); // [1, 2, '1', 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}]


輸出結果:升級版存在1個bug:無法去重(區(qū)分)多個對象,即原數組中除第一個對象可以去重外,所有對象都會被去(忽略)掉;

缺點總結:無法去重(區(qū)分)多個對象

bug - 對象去重,僅限原數組中的第一個對象,其他所有對象都會被去(忽略)掉;

如果數組中存在多個對象,除了數組中的第一個對象,所有的對象都會被過濾(不管該對象是否重復都會被去掉)。 

——分析去重過程 ——

使用filter函數,過濾出一個新數組,也就是最終的去重后的數組。

三元表達式,主要是為了得到判斷結果:true或false,然后return這個true或false這個結果,以便filter函數過濾出一個不包含重復項的新數組

① 當obj.hasOwnProperty(typeof item + item)為 false 時,說明obj對象中不存在(typeof item + item)這個自有屬性,也就是說當前循環(huán)的arr中的item項的值,沒有讓typeof item + item成為obj的私有屬性,obj不存在(typeof item + item)這個屬性

此時,整個三元表達式的值為(obj[typeof item + item] = true),整個值的真假(true 或 flase)決定了filter函數當前循環(huán)的item值是否能成為filter過濾出的新數組的元素。

因為目前obj中不存在(typeof item + item)這個自有屬性,所以obj[ typeof item + item ] =undefined,所以undefined = true為true,說明當前循環(huán)的arr中的item項,符合條件,會加入filter函數過濾后的新數組

② 當obj.hasOwnProperty(typeof item + item)為 true 時,說明obj對象中已存在(typeof item + item)這個自有屬性,

此時,三元表達式的值為false,說明當前循環(huán)的arr中的item項,不符合條件,不會加入filter函數過濾后的新數組

舉個例子:array[0]和array[4]分別被 typeof 拼接成 "number1" 和 "stringtrue",很好的區(qū)分了不同類型轉字符串后的區(qū)別

但是如果數組中存在對象,比如[ { name: 97 }, { descript: 'z' } ],由于 typeof item + item 的結果都會是 object[object Object] (String類型),所以除了數組中的第一個對象,所有的對象都會被過濾(不重復的對象也會被去掉)

改進2.0 :JSON.stringify() - 終極解決方案!

然而,即便如此,我們依然無法正確區(qū)分出兩個對象,比如 {value: 1} 和 {value: 2},因為 object[typeof item + item] 的結果都會是 object[object Object],所以我們可以使用 JSON.stringify() 將對象序列化,來避免相同的鍵值對。

let arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
 
let obj={}
 
let result=arr.filter((item)=>{
   return obj.hasOwnProperty(
   //因為JSON.stringify(NaN)==null,所以先檢測是否為數字類型,數字類型直接返回,否則再JSON.stringify
    typeof item=="number"?item:JSON.stringify(item))?
    false:(obj[typeof item=="number"?item:JSON.stringify(item)]=1);
})
 
// 全都可以去重,完美解決方案!
console.log(result) // [1, 2, '1', 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {}, {a:1}, {b:2}]


輸出結果:全都可以去重,無bug,完美解決方案! 

我的結論:Object鍵值對 + hasOwnProperty() + typeOf + JSON.stringify() 判斷依據是全等===——值和類型都相同,才去重

七、利用filter() + indexOf()去重

用法:array.indexOf(item,start) 

start:可選的整數參數。規(guī)定在數組中開始檢索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略該參數,則將從字符串的首字符開始檢索。

var arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN,NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
 
function unique(arr) {
  return arr.filter(function (item, index, arr) {
    //當前元素,在原始數組中的第一個索引==當前索引值,否則返回當前元素
    return arr.indexOf(item, 0) === index;
  });
}
// 
console.log(unique(arr)); // [1, 2, '1', 'true', true, 15, false, undefined, null, 'NaN', 0, 'a', {} , {} , {a:1} , {b:2} , {a:1}]

輸出結果:對象 無法去重,且NaN會被去(忽略)掉,直接消失了,其他都可以去重,包括null。indexOf() 方法無法識別數組的 NaN 和 {} 成員。

我的結論:filter() 判斷依據是全等===——值和類型都相同,才去重

八、利用遞歸去重

var arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
 
function unique(arr) {
  var array = arr;
  var len = array.length;
  array.sort(function (a, b) { // 排序后更加方便去重
    return a - b;
  })
 
  function loop(index) {
    if (index >= 1) {
      if (array[index] === array[index - 1]) {
        array.splice(index, 1);
      }
      loop(index - 1); // 遞歸loop,然后數組去重
    }
  }
  loop(len - 1);
  return array;
}
// 
console.log(unique(arr)) // [1, '1', true, 2, 'true', false, null, 0, true, 15, NaN, NaN, 'NaN', 'a', {…}, {…}, {…}, {…}, {…}, undefined]

輸出結果:NaN 和 對象 無法去重,其他都可以實現去重,包括null。indexOf() 方法無法識別數組的 NaN 和 {} 成員。

我的結論:遞歸去重法的判斷依據是全等===——值和類型都相同,才去重

九、利用Set數據結構(ES6)

隨著 ES6 的到來,去重的方法又有了進展,比如我們可以使用 Set 和 Map 數據結構,以 Set 為例,ES6 提供了新的數據結構 Set。它類似于數組,但是成員的值都是唯一的,沒有重復的值。Set 本身是一個構造函數,用來生成 Set 數據結構。

因為Set是一個類似數組結構,所以需要用 Array.from() 方法解析類數組為數組,將其轉型為真正的數組去使用。Array.from 方法可以將 Set 結構轉為數組。

var arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
 
function unique (arr) {
  return Array.from(new Set(arr))
}
// 對象 無法去重,會被保留下來,但可對 NaN、null 去重
console.log(unique(arr)) 
//[1, 2, '1', "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {} , {a:1} , {b:2} , {a:1}]

甚至可以再簡化下:語法糖——復制一個數組: var arr2=[...arr1]

var arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
 
function unique(arr) {
    // 利用 [...new Set(arr)] 轉為數組后去重
    return [...new Set(arr)];
}
console.log(unique(arr));
// [1, 2, '1', 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}, {…}, {…}, {…}]

還可以再簡化下:轉為ES6 箭頭函數

var arr = [1, 1, 2, '1', 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}, { a: 1 }, { b: 2 }, { a: 1 }];
 
var unique = (arr) => [...new Set(arr)]
 
console.log(unique(arr));
// (18) [1, 2, '1', 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}, {…}, {…}, {…}]

注:不考慮兼容性,這種使用Set數據結構去重的方法代碼最少。而且這種方法還無法去重對象,不過可以對NaN、null進行去重,因為 Set 加入值時認為NaN等于自身,后面的高階方法會添加去掉重復“{}”的方法。

輸出結果:對象 無法去重,其他都可以實現去重,包括NaN、null 

我的結論:newSet() 判斷依據是全等===——值和類型都相同,才去重

十、利用Map數據結構去重(ES6

了解Map數據結構

Map數據結構。它類似于對象,也是鍵值對的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當作鍵。也就是說,Object結構提供了“字符串—值”的對應,Map 結構提供了“值—值”的對應,是一種更完善的 Hash 結構實現。

Map 與 Object 的區(qū)別:Object里的屬性是字符串;Map里的key可以是任意的數據類型 key:value

對Map來說,我們可以通過使用set,get,has,delete等方法來對Map進行操作

創(chuàng)建一個空Map數據結構,遍歷需要去重的數組,把數組的每一個元素作為key存到Map中,由于Map中不會出現相同的key值,所以,最終得到的就是去重后的結果。

var arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
 
function unique(arr) {
  // Map與Object的區(qū)別 Object里的屬性是字符串;Map里的key可以是任意的數據類型 key:value
  let map = new Map();
  let array = new Array(); // 數組用于返回結果
  for (let i = 0; i < arr.length; i++) {
    // has方法返回一個布爾值,表示某個鍵是否在當前 Map 對象之中。
    if (map.has(arr[i])) { // 如果有該key值
      // set方法設置鍵名key對應的鍵值為value,然后返回整個 Map 結構。如果key已經有值,則鍵值會被更新,否則就新生成該鍵。
      map.set(arr[i], true);
    } else {
      map.set(arr[i], false); // 如果沒有該key值
      array.push(arr[i]);
    }
  }
  return array;
}
// 
console.log(unique(arr)) 
// [1, 2, '1', 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}, {…}, {…}, {…}]


輸出結果:對象 無法去重,其他都可以實現去重,包括NaN、null 

我的結論:Map數據結構去重法 判斷依據是全等===——值和類型都相同,才去重

十一、利用Map數據結構 + filter()

var arr = [1, 1, 2, '1', 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}, { a: 1 }, { b: 2 }, { a: 1 }];
 
function unique(arr) {
  const seen = new Map()
  return arr.filter((item) => !seen.has(item) && seen.set(item, 1))
}
 
console.log(unique(arr));
// [1, 2, '1', 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}, {…}, {…}, {…}]


輸出結果:對象 無法去重,其他都可以實現去重,包括NaN、null 

我的結論:Map數據結構去重法 判斷依據是全等===——值和類型都相同,才去重

十二、利用reduce() + includes()去重

Array.reduce 為數組的歸并方法,使用場景很多,比如求和(累加)、求乘積(累乘),計次,去重,多維轉一維,屬性求和等...

var arr=[1,1,2,'1','true','true',true,true,15,15,false,false,undefined,undefined,null,null,NaN, NaN,'NaN',0,0,'a','a',{},{},{a:1},{b:2},{a:1}];
function unique(arr) {
  return arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}
 
// 對象 無法去重
console.log(unique(arr));
// [1, 2, '1', 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}, {…}, {…}, {…}]

輸出結果:對象 無法去重,其他都可以實現去重,包括NaN、null 

我的結論:reduce() + includes()去重法 判斷依據是全等===——值和類型都相同,才去重

十三、利用findIndex() + Object.is()去重

—— findIndex() ——

findIndex() 方法返回傳入一個測試條件(函數)符合條件的數組第一個元素位置。

findIndex() 方法為數組中的每個元素都調用一次函數執(zhí)行:

  • 當數組中的元素在測試條件時返回 true 時, findIndex() 返回符合條件的元素的索引位置,之后的值不會再調用執(zhí)行函數。
  • 如果沒有符合條件的元素返回 -1

注意: findIndex() 對于空數組,函數是不會執(zhí)行的。

注意: findIndex() 并沒有改變數組的原始值。

—— Object.is() ——

Object.is() 方法用來判斷兩個值是否相等,它接收兩個參數,分別是需要比較的兩個值。

返回一個 Boolean 值表示這兩個值是否相等。

var arr = [1, 1, 2, '1', 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}, { a: 1 }, { b: 2 }, { a: 1 }];
 
function unique(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    // Object.is()方法認為NaN等于自身
    if (result.findIndex(value => Object.is(arr[i],value)) === -1) {
      result.push(arr[i]);
    }
  }
  return result;
}
// 
console.log(unique(arr));

輸出結果:對象 無法去重,其他都可以實現去重,包括NaN、null 

我的結論:reduce() + includes()去重法 判斷依據是全等===——值和類型都相同,才去重

十四、對象數組去重 

方法一:使用Map數據結構

Map是一組鍵值對的結構,用于解決以往不能用對象做為鍵的問題,具有極快的查找速度。(注:函數、對象、基本類型都可以作為鍵或值。

const ary = [{id: 1, text: "1"}, {id: 1, text: "1"}, {id: 2, text: "2"}, {id: 3, text: "3"}];
 
const myseta = (ary) => {
  const map = new Map();
  return ary.filter((ary) => !map.has(ary.id) && map.set(ary.id, 1))
};
 
console.log(myseta(ary)); // [{id: 1, text: '1'}, {id: 2, text: '2'}, {id: 3, text: '3'}]

方法二:使用Set數據結構

JSON.stringify + new Set( ) + Array.from() + JSON.parse

使用Set數據結構去除重復對象,必須把對象轉為string字符串形式,才可以實現對象去重,所以需要new Set(strings)進行轉型。

因為Set數據結構并非真正的數組,它類似于數組,并且成員值都是唯一的,沒有重復,所以可以用來做去重操作。但是因為它是一個類似數組結構,所以需要轉型為真正的數組去使用。所以,需要用Array.from

const ary = [{id: 1, text: "1"}, {id: 1, text: "1"}, {id: 2, text: "2"}, {id: 3, text: "3"}];
const myseta = (ary) => {
  const strings = ary.map((item) => JSON.stringify(item))
  // 使用Set數據結構去重對象
  // return new Set(strings)
 
  // 使用Array.from()把Set數據結構去重對象后的結構,轉為數組
  // return Array.from(new Set(strings))
 
  // 使用Array.from()轉為數組,然后再使用數組的map方法把數組里面的字符串類型轉化為對象類型:
  return Array.from(new Set(strings)).map((item) => JSON.parse(item))
 
};
 
// console.log(myseta(ary)); // Set(3) {'{"id":1,"text":"1"}', '{"id":2,"text":"2"}', '{"id":3,"text":"3"}'}
// console.log(myseta(ary)); // ['{"id":1,"text":"1"}', '{"id":2,"text":"2"}', '{"id":3,"text":"3"}']
console.log(myseta(ary)); // [{"id":1,"text":"1"}', '{"id":2,"text":"2"}', '{"id":3,"text":"3"}]

定義和用法

map() 方法返回一個新數組,數組中的元素為原始數組元素調用函數處理后的值。

map() 方法按照原始數組元素順序依次處理元素。

注意: map() 不會對空數組進行檢測。

注意: map() 不會改變原始數組。

方法總結

如果有如下這樣一個數組 :

var arr = [ 0, 0, 1, 1, '1', '1', 'true', 'true', true, true, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 'a', 'a', new String('1'), new String('1'), /a/, /a/, {}, {}, { a: 1 }, { b: 2 }, { a: 1 }];

由于各去重方法的兼容性不同,所得到的去重結果就會有所有不同,下面來查看一下各方法的兼容性差異: 

方法結果說明
for循環(huán)[0, 1, '1', 'true', true, false, undefined, null, NaN, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?NaN 和 對象、正則、構造函數不去重;
splice() + for循環(huán)[0, 1, 'true', undefined, NaN, NaN, 'NaN', 'a', /a/, /a/, {…}, {…}, {…}, {…}, {…}]?NaN 和 對象、正則不去重;null、構造函數被忽略掉;字符串數字、boolean的true、false轉為數字
indexOf() + for循環(huán)[0, 1, '1', 'true', true, false, undefined, null, NaN, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?NaN 和 對象、正則、構造函數不去重;
sort() + for循環(huán)[/a/, /a/, 0, 1, String, NaN, NaN, 'NaN', {…}, {…}, {…}, {…}, {…}, 'a', false, null, 'true', true, undefined]?NaN 和 對象、正則不去重;new String('1') 和 ‘1’等價,所以會去重
includes() [0, 1, '1', 'true', true, false, undefined, null, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?對象、正則、構造函數不去重
優(yōu)化后的鍵值對方法[0, 1, '1', 'true', true, false, undefined, null, NaN, 'NaN', 'a', /a/, {…}, {…}]?全去重,完美解決方案!
filter()+indexOf()[0, 1, '1', 'true', true, false, undefined, null, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?對象、正則、構造函數不去重;NaN會被忽略掉
遞歸[0, false, null, 1, '1', 'true', true, NaN, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}, undefined]?NaN 和 對象、正則、構造函數不去重;
Set數據結構[0, 1, '1', 'true', true, false, undefined, null, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?對象、正則、構造函數不去重;
Map數據結構[0, 1, '1', 'true', true, false, undefined, null, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?對象、正則、構造函數不去重;
Map數據結構 + filter()[0, 1, '1', 'true', true, false, undefined, null, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?對象、正則、構造函數不去重;

reduce() + includes()

[0, 1, '1', 'true', true, false, undefined, null, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?對象、正則、構造函數不去重;
findIndex() + Object.is()[0, 1, '1', 'true', true, false, undefined, null, NaN, 'NaN', 'a', String, String, /a/, /a/, {…}, {…}, {…}, {…}, {…}]?對象、正則、構造函數不去重;

注意:上述表格的說明部分,除了不去重的、被去重跳過忽略掉的之外,其他的都可以實現去重,包括null、NaN(當然,僅限在去重數組范圍內的項,不在測試去重數組范圍內其他類型數據,大家可自行測試。),以上方法的整理總結,如有錯誤之處,還請大家評論指出!

寫在最后

雖然各個方法去重的結果有所不同,但更重要的是讓我們知道在合適的場景要選擇合適的去重方法。

另外,還有很多文章提到其他去重的方法,比如,foreach + indexOf 數組去重的方法,不過,實現的過程,個人覺得都是大同小異。如果還有其他比較好的去重方法,歡迎評論給出!

以上就是JavaScript實現數組去重的14種方法大全的詳細內容,更多關于JavaScript數組去重的資料請關注腳本之家其它相關文章!

相關文章

  • javascript 構建模塊化開發(fā)過程解析

    javascript 構建模塊化開發(fā)過程解析

    這篇文章主要介紹了javascript 構建模塊化開發(fā)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • javaScript使用EL表達式的幾種方式

    javaScript使用EL表達式的幾種方式

    這篇文章主要介紹了javaScript如何使用EL表達式,有哪幾種不錯的方式,需要的朋友可以參考下
    2014-05-05
  • JS按鈕閃爍功能的實現代碼

    JS按鈕閃爍功能的實現代碼

    js按鈕閃爍功能的實現代碼分為html和js兩部分代碼,具體實現代碼大家參考下本文
    2017-07-07
  • JS創(chuàng)建自定義對象的六種方法總結

    JS創(chuàng)建自定義對象的六種方法總結

    這篇文章主要給大家介紹了關于JS創(chuàng)建自定義對象的六種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • 淺析Javascript的自動分號插入(ASI)機制

    淺析Javascript的自動分號插入(ASI)機制

    我們大家都知道在寫java和c時,必須要在語句后加分號,否則編譯通不過。而js不同,存在自動分好插入機制,下文簡稱ASI。它會給源代碼的 token 流自動插入分號。下面這篇文章我們就來談談Javascript的自動分號插入(ASI)機制。
    2016-09-09
  • Knockoutjs 學習系列(二)花式捆綁

    Knockoutjs 學習系列(二)花式捆綁

    這篇文章主要介紹了Knockoutjs 學習系列(二)花式捆綁 的相關資料,主要介紹了knockoutjs中各種綁定的使用方法,非常不錯具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • JavaScript異步編程 Async/Await 使用從原理到最佳實踐記錄

    JavaScript異步編程 Async/Await 使用從原理到最佳實踐記錄

    Async/Await 的引入徹底改變了 JavaScript 異步編程的面貌,通過本文的講解,相信小伙伴們可以掌握 Async/Await 的使用精髓,將使您的 JavaScript 代碼在保持高性能的同時,獲得質的可讀性和可維護性提升,感興趣的朋友一起看看吧
    2025-05-05
  • 前端原生js實現拖拽排課效果實例

    前端原生js實現拖拽排課效果實例

    這篇文章主要介紹了如何實現一個簡單的課程表拖拽功能,通過HTML、CSS和JavaScript的配合,我們實現了課程項的拖拽、放置和顯示功能,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2025-02-02
  • 一文詳解如何跳出map或者foreach循環(huán)

    一文詳解如何跳出map或者foreach循環(huán)

    javascript中的遍歷方法有很多,今天主要總結一下這些遍歷方法如何跳出循環(huán),這篇文章主要給大家介紹了關于如何跳出map或者foreach循環(huán)的相關資料,需要的朋友可以參考下
    2023-11-11
  • 超出JavaScript安全整數限制的數字計算BigInt詳解

    超出JavaScript安全整數限制的數字計算BigInt詳解

    這篇文章給大家分享了超出JavaScript安全整數限制的數字計算BigInt的相關知識點,有興趣的朋友參考學習下。
    2018-06-06

最新評論

翁牛特旗| 慈溪市| 宁南县| 元阳县| 巫溪县| 梅州市| 翼城县| 嵊泗县| 兴安盟| 林芝县| 日照市| 军事| 阿坝| 沙坪坝区| 田林县| 雅安市| 双城市| 靖边县| 宁蒗| 永春县| 恭城| 甘泉县| 西充县| 青浦区| 绥宁县| 黎川县| 临西县| 马龙县| 呼和浩特市| 万荣县| 云霄县| 铜梁县| 略阳县| 浦东新区| 南召县| 石阡县| 安塞县| 泽州县| 临安市| 无为县| 宁晋县|