javascript多种方法实现数组去重

简介: 先说说这个实例的要求:写一个方法实现数组的去重。(要求:执行方法,传递一个数组,返回去重后的新数组,原数组不变,实现过程中只能用一层循环,双层嵌套循环也可写,只做参考);先给初学者解释一下什么叫数组去重(老鸟跳过):意思就是讲数组里面重复的元素去掉,比如说var arr = [3,2,4,2,1,2]; 数组去重得到的新数组是 [3,2,4,1],就是这么一个功能。

先说说这个实例的要求:写一个方法实现数组的去重。(要求:执行方法,传递一个数组,返回去重后的新数组,原数组不变,实现过程中只能用一层循环,双层嵌套循环也可写,只做参考);

先给初学者解释一下什么叫数组去重(老鸟跳过):意思就是讲数组里面重复的元素去掉,比如说var arr = [3,2,4,2,1,2]; 数组去重得到的新数组是 [3,2,4,1],就是这么一个功能。

 

第一种,通过遍历新数组来去重

var arr = [1,'b','b',4,3,3,4,5,1]; 

        //第一种

        Array.prototype.unique1 = function(){

            var arr1 = []; //定义一个新数组

            for(var i=0;i<this.length;i++){

                if(arr1.indexOf(this[i]) == -1){//判断目标数组中在原数组里是否存在

                    arr1.push(this[i]);

                } 

            } 

            return arr1;

        }

        console.log(arr); //[1,'b','b',4,3,3,4,5,1]

        console.log(arr.unique1()); //[1, "b", 4, 3, 5]

        //这种方法的主要思路就是,新建一个数组,然后在原数组中,从第一个开始,看看新数组里面有没有这个元素,如果有,就忽略,然后进行下一个,如果没有,则把这个元素存到新数组里面,

        //也就是说,每一次比较,都会遍历新数组,直到找到相同元素为止,比较耗性能

如果大家不习惯这个写法,可以改成下面的写法,效果是一样的:

var arr = [1,'b','b',4,3,3,4,5,1];

function unique1(arr){

            var arr1 = [];

            for(var i=0;i<arr.length;i++){

                if(arr1.indexOf(arr[i]) == -1){//判断目标数组中在原数组里是否存在

                    arr1.push(arr[i]);

                } 

            } 

            return arr1;

        }

        console.log(arr); //[1,'b','b',4,3,3,4,5,1]

        console.log(unique1(arr)); //[1, "b", 4, 3, 5]

下面的方法我就不改写法了,你们可以按照上面的格式来改写一下,结果我也不输出了,因为结果是一样的,注释写在代码中,慢慢体会一下

 

第二种,通过hash表(这个概念有点大,这是好东西)实现

var arr = [1,'b','b',4,3,3,4,5,1];

Array.prototype.unique2 = function(){

            var hash = {}; //定义一个hash表

            var arr1 = [];  //定义一个新数组

            for(var i=0;i<this.length;i++){

                /*

                    这里比较难理解,我们一步一步来看:

                    hash是一个对象,则存在键值对(key:value),只不过现在是为空的,所以hash[key] = value;

                    第一步:i=0;this[i]=this[0]=1; hash[this[0]] = hash[1] , 因为hash初始为空,没有找到key=1的值,所以然后undefined,

                    执行下一步:hash[1] = true(此时hash对象就有了第一组键值对),将原数组的第一个数添加到新数组中,重复第一步

                    因为不重复的判断hash的值都是undefined,而重复的都为true了,所以不重复都被添加到新数组中

                    因为hash表存的值是存的地址,放在堆内存中,所以有多少个不重复的元素,就要分多少个内存来存放,所以这种方法比较占内存,但是相比之下,这种的运算运动是最快的,

                    这也就是用空间来换取时间了,数据量比较小,推荐用此方法

                */

                if(! hash[this[i]]){

                    hash[this[i]] = true;

                    arr1.push(this[i]);

                }

            }

            return arr1;  

        }

        console.log(arr);

        console.log(arr.unique2());

 

第三种,通过遍历自身的位置是否一致来实现

var arr = [1,'b','b',4,3,3,4,5,1];

Array.prototype.unique3 = function(){

            var arr1 = [];  //定义一个新数组

            for(var i=0;i<this.length;i++){

                if(this.indexOf(this[i])==i){

                //这里也是indexOf遍历,看从第一个元素在原数组中的位置,如果第一次出现的位置和下标相等,说明当前元素的不重复的,如果不等,说明该元素前面已经出现过

                    arr1.push(this[i]);

                }

            }

            return arr1;  

        }

        console.log(arr);

        console.log(arr.unique3());

 

第四种,这个有点意思,只能运用到特殊场合,就是先跟数组排序,然后22比较,输出一个排序过的新数组

Array.prototype.unique4 = function(){

            /*

                这里是思路是,先排序(默认从小到大),然后将原数组的第一个给新数组,

                因为是经过排序的,所以重复的只会存在在相邻位置

                这里就相当于是做22比较,如果相等,则进行下一组,如果不相等,则把这个数存到新数组中,用这个数再进行比较

            */

            this.sort();

            var arr1 = [this[0]];

            for(var i=1;i<this.length;i++){

                if(this[i] !== arr1[arr1.length-1]){

                    arr1.push(this[i]);

                } 

            }

            return arr1;  

        }

        console.log(arr);

        console.log(arr.unique4());

 

要求里面还说,可以使用双层嵌套循环来实现,无法就是用2层for循环,让每一个与原数组去比较

Array.prototype.unique5 = function(){

            //双层循环,一一比较

            for(var i=0;i<this.length;i++){ //从0开始

                for(j= i+1;j<this.length;j++){ //从1开始,逐个比较

                    if(this[i] === this[j]){ //如果恒定

                        this.splice(j,1);   //就将这个元素删掉

                    } 

                } 

            }

            return this;  

        }

        console.log(arr);

        console.log(arr.unique5());

 

这种写法的循环次数太多,不推荐,有人会说,第一种和第三种不也是每次都遍历一遍吗?跟第5种感觉也差不多呢?是的,你能这么理解,说明你理解了,但是呢,又不是特别的理解,我们说差不多那可就差太多了,indexOf()表示的是找到第一个匹配的元素就会停止遍历,而第5种则是不管找不找得到,都会把整个数组遍历一遍,如果数据量大,那你觉得哪个性能要好一点?

特别注意的一点:如果在比较两两之间的值是全等或不等的时候,一定要用恒定(===)和不恒定(!==),因为这会涉及到元素的类型上,如 1与'1'是不恒等的!

 

 

相关文章
|
7天前
|
存储 JavaScript 索引
JS中数组的相关方法介绍
JS中数组的相关方法介绍
|
7天前
|
JavaScript Java
JS有趣的灵魂 清空数组
JS有趣的灵魂 清空数组
|
9天前
|
JavaScript 前端开发 容器
AJAX载入外部JS文件到页面并让其执行的方法(附源码)
AJAX载入外部JS文件到页面并让其执行的方法(附源码)
13 0
|
10天前
|
JSON JavaScript 前端开发
JavaScript原生代码处理JSON的一些高频次方法合集
JavaScript原生代码处理JSON的一些高频次方法合集
|
1月前
|
JavaScript 前端开发 API
常用JavaScript 数组 API大全
常用JavaScript 数组 API大全
32 0
|
1月前
|
JavaScript 前端开发
解释 JavaScript 中的`map()`、`filter()`和`reduce()`方法的用途。
解释 JavaScript 中的`map()`、`filter()`和`reduce()`方法的用途。
17 1
|
7天前
|
JavaScript 前端开发 索引
JavaScript中与字符串相关的方法
JavaScript中与字符串相关的方法
|
1天前
|
JavaScript 前端开发
js绑定事件的方法
js绑定事件的方法
17 11
|
2天前
|
JavaScript
JS生成uuid的四种方法
JS生成uuid的四种方法
4 0
|
2天前
|
JavaScript 前端开发 iOS开发
js实用方法记录-动态加载css/js
js实用方法记录-动态加载css/js
9 0