欢迎光临散文网 会员登陆 & 注册

数组去重(算法整理)

2019-07-19 20:13 作者:Alice铛铛铛  | 我要投稿

for...of循环的i代表的是value(多用于数组),for...in循环的是key(多用于对象)

方法一:哈希表思想(最高性能)

思路:新建一个结果数组、一个存储标志的对象hash,遍历数组,对象中arr[i]对应的值为ture的时候不重复添加;

       function unique( arr )  {
               var result = [] ,
                       hash = {} ;  // 定义新数组result 和hash.
               for ( let elem of arr )  {  //  遍历前四个数时,hash表中没有这四个值,所以if语句成立,将数据push到result中,令这些表中的数都为true。

                       if ( ! hash [ elem ] ) //  当遍历到第二个1的时候,之前已经令hash [ elem ]  = true , 所以if语句就不执行了,就不会重复了

                               result.push ( elem );
                               hash [ elem ] = true; // 作为一个是否在数组中存在的标志
                       }
               }
               return result;
       }
       var arr = [1, 23, 34, 45, 1, 6, 4, 23];
       unique ( arr ) ; // [1, 23, 34, 45, 6, 4]

方法二:遍历数组,用indexOf() / includes()

思路1:新建一个数组result,遍历原数组,arr[i]不存在于新数组中,就添加push进新数组,得到的新数组就是不重复的。

    function unique ( arr ) {
             var result = [] ;
             for ( var i = 0 ; i < arr.length ; i++ )  {
                    if ( result . indexOf ( arr [ i ] ) == -1 ) { //indexOf等于-1时代表数组中没有该值
                            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:新建一个数组result,如果新数组中该值i不存在,则将原数组内容添加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]

方法三:数组下标判断法

思路1:利用indexOf返回的始终是第一个相同数值的下标,如果新增的内容在原来数组中的下标和现在的下标不同,那么就证明它是重复的

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 ]


方法四:排序,去除相邻的重复值

思路:给数组排序,排序后相同的值会相邻,遍历排序后的数组时,新数组只加入不与前一值重复的值。

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 循环可以简写成 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 ]

方法五:双层循环遍历

思路1:有重复值时终止当前循环i进入外层循环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:两层循环遍历,如果有重复的值,则用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 会改变原数组长度,所以要将数组长度 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函数可以接受一个数组作为参数,用来初始化。

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()方法的过滤方法,将数组进行过滤,筛选条件是数组下标与检索下标一致。

concat()方法用于连接两个或多个数组;该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

filter ( ) 方法通过检查指定数组中符合条件的所有元素;不会改变原始数组,创建一个新的数组。

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 ]


数组去重(算法整理)的评论 (共 条)

分享到微博请遵守国家法律