1. 程式人生 > >深入淺出:瞭解世上最全的陣列去重方式

深入淺出:瞭解世上最全的陣列去重方式

 //第一種:IndexOf(最簡單陣列去重法)/** 新建一新陣列,遍歷傳入陣列,值不在新陣列就push進該新陣列中* IE8以下不支援陣列的indexOf方法* */ function uniq(array) { var temp = []; //一個新的臨時陣列 for (var i = 0; i < array.length; i++) { if (temp.indexOf(array[i]) == -1) { temp.push(array[i]); } } return temp; } var aa = [{}, {}, 2, 4, 9, 6, 7, 5, 2, 3, 5
, 6, 5]; var bb = [2, 4, 9, 6, 7, 5, 2, 3, 5, 6, 5] console.log(uniq(aa)); //[{},{},2,4,9,6,7,5,3] 無法去除空物件 console.log(uniq(bb)); //[2,4,9,6,7,5,3]

(2)也可以用lastIndexOf 

function unique(arr){ var res = []; for(var i=0; i<arr.length; i++){ res.lastIndexOf(arr[i]) !== -1 ? '' : res.push(arr[i]); } return
res;} console.log(unique([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4, {}, {},[],[]]));//[1, 2, 3, 5, 6, 7, 4, {}, {}, Array(0), Array(0)]//第二種去重:(可去重複物件)/** 速度最快, 佔空間最多(空間換時間)** 該方法執行的速度比其他任何方法都快, 就是佔用的記憶體大一些。* 現思路:新建一js物件以及新陣列,遍歷傳入陣列時,判斷值是否為js物件的鍵,* 不是的話給物件新增該鍵並放入新陣列。* 注意點:判斷是否為js物件鍵時,會自動對傳入的鍵執行“toString()”,* 不同的鍵可能會被誤認為一樣,例如n[val]-- n[1]、n["1"];* 解決上述問題還是得呼叫“indexOf”。*/ function
uniq(array) { var temp = {}, arr = [], len = array.length,val, type; for (var i = 0; i < len; i++) { val = array[i]; type = typeof val; if (!temp[val]) { temp[val] = [type]; arr.push(val); } else if (temp[val].indexOf(type) < 0) { temp[val].push(type); arr.push(val); } } return arr; } var aa = [1, 2, "2", 4, 9, "a", "a", 2, 3, 5, 6, 5]; var bb = [{a:1},{a:1},[],[],NaN,NaN,null,null,1,1,"1","1","a","a"] console.log(uniq(aa));// [1, 2, "2", 4, 9, "a", 3, 5, 6] console.log(uniq(bb));// [{a:1}, Array(0), NaN, null, 1, "1", "a"]

// 第三種去重(無法去空物件)

/** 給傳入陣列排序,排序後相同值相鄰,* 然後遍歷時,新陣列只加入不與前一值重複的值。* 會打亂原來陣列的順序* */ function uniq(array){ array.sort(); var temp=[array[0]]; for(var i = 1; i < array.length; i++){ if( array[i] !== temp[temp.length-1]){ temp.push(array[i]); } } return temp; } var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5]; var bb = [{},{},[],[],NaN,NaN,1,1,"a","a","b","c"]; console.log(uniq(aa));//[1, "2", 2, 3, 4, 5, 6, 9, "a"] console.log(uniq(bb));// [Array(0), Array(0), 1, NaN, NaN, {…}, {…}, "a", "b", "c"]

第四種去重(無法去空物件,會把NaN刪掉)

* 還是得呼叫“indexOf”效能跟方法1差不多,* 實現思路:如果當前陣列的第i項在當前陣列中第一次出現的位置不是i,* 那麼表示第i項是重複的,忽略掉。否則存入結果陣列。* */ function uniq(array){ var temp = []; for(var i = 0; i < array.length; i++) { //如果當前陣列的第i項在當前陣列中第一次出現的位置是i,才存入陣列;否則代表是重複的 if(array.indexOf(array[i]) == i){ temp.push(array[i]) } } return temp; } var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5]; var bb = [{},{},[],[],NaN,NaN,1,1,"a","a","b","c"]; console.log(uniq(aa));//[1, "2", 2, 3, 4, 5, 6, 9, "a"] console.log(uniq(bb));// [{…}, {…}, Array(0), Array(0), 1, "a", "b", "c"]

//第五種:定義一個新陣列,並存放原陣列的第一個元素,然後將元素組一一和新陣列的元素對比,若不同則存放在新陣列中。(無法去除空物件)

function unique(arr) { var res = [arr[0]]; for (var i = 1; i < arr.length; i++) { var repeat = false; for (var j = 0; j < res.length; j++) { if (arr[i] === res[j]) { repeat = true; break; } } if (!repeat) { res.push(arr[i]); } } return res; } console.log(unique([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4, {}, {},[],[]]));//[1,2,3,5,6,7,4,{},{},[],[]]

// 第六種去重(無法去空物件)

// 思路:獲取沒重複的最右一值放入新陣列* 推薦的方法* 方法的實現程式碼相當酷炫,* 實現思路:獲取沒重複的最右一值放入新陣列。* (檢測到有重複值時終止當前迴圈同時進入頂層迴圈的下一輪判斷)*/ function uniq(array) { var temp = []; var l = array.length; for (var i = 0; i < l; i++) { for (var j = i + 1; j < l; j++) { if (array[i] === array[j]) { i++; j = i; } } temp.push(array[i]); } return temp; } var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5]; var bb = [{},{},[],[],NaN,NaN,1,1,"a","a","b","c"]; console.log(uniq(aa));// [1, "2", 4, 9, "a", 2, 3, 6, 5] console.log(uniq(bb));// [{…}, {…}, Array(0), Array(0), NaN, NaN, 1, "a", "b", "c"]

 第六種:物件去重:(利用屬性名不重複,後面會覆蓋前面,可去空物件)

var ary1 =[{},{},[],[],"a","a",1,2,2,1,6,NaN,NaN,null,null];     function uniq(ary1){         var obj={};         var arr=[];      for (var key in ary1){       obj[ary1[key]]=ary1[key]         }      for(var key in obj){     arr.push(obj[key]) } console.log(arr);//[1, 2, 6, {…}, Array(0), "a", NaN, null] } uniq(ary1)

 第七種去重(es6):

1.Set去重:ES6中新增了Set資料結構,類似於陣列,但是 它的成員都是唯一的 ,其建構函式可以接受一個數組作為引數,如:

let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3]; let set = new Set(array); console.log(set); // => Set {1, 2, 3, 4, 5};

2.Set配合Array.from

ES6中新增了一個靜態方法可以把類似陣列的物件轉換為陣列,如通過querySelectAll方法得到HTML DOM Node List,以及ES6中新增的等可遍歷物件,如:

let array = Array.from(new Set([1, 1, 1, 2, 3, 2, 4])); console.log(array); // => [1, 2, 3, 4]

3.Map物件(無法去重複空物件)

var arr =[{},{},[],[],"a","a",1,2,2,1,6,NaN,NaN,null,null]; var brr = ["a","a",1,2,2,1,6] function unique(arr) { const res = new Map(); return arr.filter((a) => !res.has(a) && res.set(a, 1)) } console.log(unique(arr))//[{…}, {…}, Array(0), Array(0), "a", 1, 2, 6, NaN, null] console.log(unique(brr))// ["a", 1, 2, 6]

4.filter(無法去重複空物件)

var oldArr = [1, 2, 1, 2, 1, 23, 4, 1, 23, 24, 4, 5, 2, 3, 6, 7]; var oldArr1 = [{},{},[],[],NaN,NaN,"a","a"] function uniq(arrs){ var arr = arrs.filter(function (item, index) { //每拿到一項,然後去看之前組成的陣列中有沒有這一項,如果有不留下,沒有的話留下 return !(arrs.slice(0, index).includes(item)); }); return arr; } console.log(uniq(oldArr));//[1, 2, 23, 4, 24, 5, 3, 6, 7] console.log(uniq(oldArr1));//[{…}, {…}, Array(0), Array(0), NaN, "a"]

5.可去重複物件的去重

var arr =[{a:1},{a:2},[],[],1,1,"a","a","b"]; (function(){//去除陣列中重複物件 var unique = {}; arr.forEach(function(a){ unique[ JSON.stringify(a) ] = 1 }); arr= Object.keys(unique).map(function(u){return JSON.parse(u) }); return arr; })(arr) console.log(arr)// [1, {a:1}, {b:2}, Array(0), "a", "b"]

以上是我找了各種示例總結的,如果道友還有,求分享一下,謝謝!