數(shù)組去重(算法整理)

思路:新建一個結果數(shù)組、一個存儲標志的對象hash,遍歷數(shù)組,對象中arr[i]
對應的值為ture
的時候不重復添加;
? ? ? ?function unique( arr )? {
? ? ? ? ? ?????var result = [] ,
? ? ? ? ? ? ? ?????????hash = {} ;??// 定義新數(shù)組result 和hash.
? ? ? ? ? ?????for ( let elem of arr )? {??//? 遍歷前四個數(shù)時,hash表中沒有這四個值,所以if語句成立,將數(shù)據(jù)push到result中,令這些表中的數(shù)都為true。
? ? ? ? ? ? ? ?????????if ( ! hash [ elem ] )? {?//? 當遍歷到第二個1的時候,之前已經(jīng)令hash [ elem ]? =?true , 所以if語句就不執(zhí)行了,就不會重復了
? ? ? ? ? ? ? ? ? ?????????????result.push ( elem );
? ? ? ? ? ? ? ? ? ?????????????hash [ elem ] = true;?// 作為一個是否在數(shù)組中存在的標志
? ? ? ? ? ? ? ?????????}
? ? ? ? ? ?????}
? ? ? ? ? ?????return result;
? ? ? ?}
? ? ? ?var arr = [1, 23, 34, 45, 1, 6, 4, 23];
? ? ? ?unique ( arr ) ;?// [1, 23, 34, 45, 6, 4]
方法二:遍歷數(shù)組,用indexOf() / includes()
思路1:新建一個數(shù)組result,遍歷原數(shù)組,當arr[i]
不存在于新數(shù)組中,就添加push
進新數(shù)組,得到的新數(shù)組就是不重復的。
????function unique ( arr ) {
?????????????var result = [] ;
?????????????for ( var i = 0 ; i < arr.length ; i++ )? {
????????? ? ????????if ( result .?indexOf ( arr [ i ] ) == -1 ) { //indexOf等于-1時代表數(shù)組中沒有該值
? ???????????????? ?????????result.push ( arr [?i ] ) ;
? ? ????????? ????? }
?????????????}
?????????????return result ;
????}
????var arr = [1, 23, 34, 45, 1, 6, 4, 23 ] ;
????unique( arr ) ;?// [1, 23, 34, 45, 6, 4 ]
思路2:新建一個數(shù)組result
,如果新數(shù)組中該值i
不存在,則將原數(shù)組內容添加push(i)
。
function unique ( arr )? {
? ?????let result = [] ;
? ?????for ( let? i? of arr) {
? ? ? ?????????! result . includes ( i ) && result . push ( i )
? ?????}
? ?????return result
}
var arr = [1, 23, 34, 45, 1, 6, 4, 23 ] ;
unique ( arr ) ; // [1, 23, 34, 45, 6, 4]
方法三:數(shù)組下標判斷法
思路1:利用indexOf返回的始終是第一個相同數(shù)值的下標,如果新增的內容在原來數(shù)組中的下標和現(xiàn)在的下標不同,那么就證明它是重復的
function unique ( arr ) {
????? var result = [] ;
?? ? ?for ( var i = 0 ;?i < arr . length ; i++ )? {
? ? ???????? if ( arr . indexOf ( arr [ i ] ) == i ){?// 下標不同,代表了重復
? ? ?????????????? result . push ( arr [ i ] ) ;
? ? ???????? }
?? ? ?}
????? return result ;
}
var arr = [1, 23, 34, 45, 1, 6, 4, 23 ] ;
unique ( arr ) ;?// [1, 23, 34, 45, 6, 4 ]
思路2(重復的直接刪除,不保留):利用indexOf和lastIndexOf,從前往后和從后往前找到的下標如果相同,就證明沒有重復的值;
????????function unique ( arr ) {
?????????????????var result = [] ;
?????????????????for ( var i = 0 ; i < arr . length ; i++ ) {
? ? ????????????????????if ( arr . indexOf ( arr [ i ] ) == arr . lastIndexOf ( arr [ i ] ) ) {
? ? ? ??????????????????????????result . push ( arr [ i ] ) ;
? ? ????????????????????}
?????????????????}
?????????????????return result ;
????????}
????????var arr =? [ 1, 23, 34, 45, 1, 6, 4, 23 ] ;
????????unique ( arr ) ;?// [ 34, 45, 6, 4 ]
方法四:排序,去除相鄰的重復值
思路:給數(shù)組排序,排序后相同的值會相鄰,遍歷排序后的數(shù)組時,新數(shù)組只加入不與前一值重復的值。
function unique(arr){
?????????arr.sort();
?????????var result=[arr[0]];
?????????for (var i = 1 ; i < arr . length ; i++ )?{
? ? ????????????if ( arr [ i ] != result [ result . length - 1 ] ) {
? ? ? ????????????????result . push ( arr [ i?] ) ;
? ? ????????????}
? ? ?????//這里的 if 循環(huán)可以簡寫成 arr [ i ]?!== arr [ i - 1 ] && result . push ( arr [ i ] )
?????????}?
?????????return result ;
}
var arr = [ 1, 23, 34, 45, 1, 6, 4, 23 ] ;
unique ( arr ) ;?// [1, 23, 34, 4, 45, 6 ]
方法五:雙層循環(huán)遍歷
思路1:有重復值時終止當前循環(huán)i
,進入外層循環(huán)i+1
;找到的是往后遍歷不會有重復值的值;
function unique ( arr ) {
?????????var result?= [] ;
?????????for ( var i = 0 ; i < arr . length ; i++ )? {
? ?????????????for (var j = i+1 ; j < arr . length ;? j++ )? {
? ? ?????????????????????if ( arr [ i ] === arr [ j ] ) {
? ? ? ?????????????????????++i ;
? ? ?????????????????????}
? ?????????????}
? ? ???????????result?. push ( arr [ i ] ) ;
?????????}
?????????return result?;
}
var arr = [ 1, 23, 34, 45, 1, 6, 4, 23 ] ;
unique ( arr ) ;?// [ 34, 45, 1, 6, 4, 23 ] 注意這里的順序和上面的都不同
思路2:兩層循環(huán)遍歷,如果有重復的值,則用splice()刪除
function unique ( a )? {
? ?????for ( let i = 0, len = arr . length ; i < len ;? i++ ) {
? ? ? ?????????for ( let j = i + 1 ; j < len ; j ++ )? {
? ? ? ? ? ?????????????if ( arr [ i ]?== arr [ j ] ) {
? ? ? ? ? ? ? ?????????????????arr . splice ( j , 1 ) ;
? ? ? ? ? ? ? ??????????// splice 會改變原數(shù)組長度,所以要將數(shù)組長度 len 和下標 j 減一
? ? ? ? ? ? ? ?????????????????len -- ;
? ? ? ? ? ? ? ?????????????????j -- ;
? ? ? ? ? ?????????????}
? ? ? ?????????}
? ??????}
? ?????return arr
}
var arr = [ 1, 23, 34, 45, 1, 6, 4, 23 ] ;
unique ( arr ) ;?// [ 1, 23, 34, 45, 6, 4 ]
方法六:ES6的Set結構(高性能)
思路:Set結構成員的值都是唯一的,Set函數(shù)可以接受一個數(shù)組作為參數(shù),用來初始化。
function unique ( arr ) {
? ????var x = new Set ( arr ) ;
?????return [ ...x ] ;
????//這里直接返回 x 的話,結果是Set ( 6 ) { 1, 23, 34, 45, 6, 4 }
? ?//上面的兩行代碼可以簡寫成:return Array . from ( new Set ( [ ...arr ] ) )
}
var arr = [ 1, 23, 34, 45, 1, 6, 4, 23 ] ;
unique ( arr ) ;?// [ 1, 23, 34, 45, 6, 4 ]
方法七:ES6的 Array.filter()
思路:利用?Array.filter()
方法的過濾方法,將數(shù)組進行過濾,篩選條件是數(shù)組下標與檢索下標一致。
concat()
方法用于連接兩個或多個數(shù)組;該方法不會改變現(xiàn)有的數(shù)組,而僅僅會返回被連接數(shù)組的一個副本。
filter ( ) 方法通過檢查指定數(shù)組中符合條件的所有元素;不會改變原始數(shù)組,創(chuàng)建一個新的數(shù)組。
function unique( arr ) {
? ?????return arr . filter ( ( item , index ) => {
? ? ? ?????????return arr . indexOf ( item ) === index
? ?????} )
}
var arr = [ 1, 23, 34, 45, 1, 6, 4, 23 ] ;
unique ( arr ) ;?// [ 1, 23, 34, 45, 6, 4 ]