深入淺出:瞭解史上最全的陣列去重方式
//第一種: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"]
以上是我找了各種示例總結的,如果道友還有,求分享一下,謝謝!