JavaScript之数组去重

  前言:昨天看到了别人发的帖子,谈到了面试题中经常出现的数组去重的问题。作为一个热爱学习、喜欢听老师话的好孩纸,耳边忽然想起来高中老师的谆谆教导:不要拿到题就先看答案,要先自己思考解答,然后再对照答案检验。于是我便开始了独立思考的过程:

  首先,我想到的是另建一个结果数组,用来存储原始数组中不重复的数据。遍历原始数组依次跟结果数组中的元素进行比较,检测是否重复。于是乎,我写出了如下代码A:

 1 Array.prototype.clearRepetitionA = function(){
 2     var result = [];
 3     var isRepetition;
 4     for(var i=0; i<this.length; i++){
 5         isRepetition = false;
 6         for(var j=0; j<result.length; j++){
 7             if(this[i] === result[j]){
 8                 isRepetition = true;
 9                 break;
10             }
11         }
12         if(!isRepetition){
13             result.push(this[i]);
14         }
15     }
16     return result;
17 } 

  写完之后,忽然想起来前几天刚看的ECMAScript 5中的数组方法 indexOf 可以检索数组元素。于是我又使用 indexOf 方法替代了第二层循环,写出了如下代码B:

1 Array.prototype.clearRepetitionB = function(){
2     var result = [];
3     for(var i=0; i<this.length; i++){
4         if(result.indexOf(this[i]) == -1){
5             result.push(this[i]);
6         }
7     }
8     return result;
9 } 

  哈,代码一下子从17行变成了9行了,简洁多了。高三数学大题解法一般都不止一种的啊,然后我就继续再想其他方法了。indexOf 方法的意思是搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引,没有找到就返回 -1 ,第一个参数就是要搜索的值,第二个参数可选:它指定数组中的一个索引,从那里开始搜索,如果省略这个参数,则从头搜索。思维一发散,想到了前面方法都是检测值是否重复的,现在有了indexOf 方法不就可以根据检测到的每个元素的第一次出现时的索引和这个元素自身的索引值比较相等来判断是否重复嘛。所以,我又写出了代码C:

1 Array.prototype.clearRepetitionC = function(){
2     var result = [this[0]];
3     for(var i=1; i<this.length; i++){
4         if(this.indexOf(this[i]) == i){
5             result.push(this[i]);
6         }
7     }
8     return result;
9 } 

  写完这个,又继续想了想,实在是想不出其他方法了(哎,这三个方法都是很基础的方法,数据结构、算法没学好,真心想不出啥惊天地、泣鬼神的牛逼方法来)。于是,我就去对照答案,检验自己了。一看答案,发现自己还是真实太弱了,简单的问题还是有些奇思妙想的。下面不是自己想的了,就不再说太多我的心路历程了。废话不多说,直接上经典的答案+解析了。

  首先,先说一个算法中经常说的以空间换时间的解法,保持队形,我们就叫它代码D吧:

 1 Array.prototype.clearRepetitionD = function(){
 2     var result = [];
 3     var obj = {};
 4     var key,type;
 5     for(var i=0; i<this.length; i++){
 6         key = this[i];
 7         type = typeof key;
 8         if(!obj[key]){
 9             obj[key] = [type];
10             result.push(key);
11         }else if(obj[key].indexOf(type)){
12             obj[key].push(type);
13             result.push(key);
14         }
15     }
16     return result;
17 } 

  这个方法中在遍历原始数组时用一个对象 obj 的属性来保存原始数组中元素的值。同时这个属性的值是一个数组,用来存储这个属性的类型,这一点可以把原始数组中类似数字1元素和字符串‘1’的元素区分开。这个方法通过额外构建一个对象的方式降低了上面三种方法中indexOf方法所花费的时间,可以说较为高效吧。

  如果你已经满足于上面所说的以空间换时间的高效方法而不继续看下去的话,那就大错特错了,好戏总在后头嘛。现在好戏开场,毫无疑问,就是代码E了:

 1 Array.prototype.clearRepetitionE = function(){
 2     var result = [];
 3     for(var i=0; i<this.length; i++){
 4         for(var j=i+1; j<this.length; j++){
 5             if(this[i] === this[j]){
 6                 j = ++i;
 7             }
 8         }
 9         result.push(this[i]);
10     }
11     return result;
12 } 

  代码D以空间换时间,感觉也就一般般。那么代码E呢?我擦,这代码是错误的吧,这个真的能去重吗?是的,起初我都没看懂这代码,看了解析后又看了一遍之后才明白过来。那么,没看懂的看官也要认真的看解析了:第一层从前往后遍历原始数组,第二层循环是检测每个元素是否跟它之后的元素重复,如果它之后有重复元素则跳过它;如果这个元素之后所有元素都跟他不重复了,则把它添加到结果数组中。这个方法实现思路就是:获取无重复的最右一值添加到结果数组中,这个跟第一种方法相比也优化了第二层的循环,效率要比它高,不过这个方法的结果数组中元素的顺序跟原始数组中元素的顺序不一样了。

  看完了代码E解析的你是不是已经伸出了大拇指、投放出了敬佩的目光呢?(这些鲜花和荣誉别给我,应该给写这个方法的大神去)。下面再说最后一个方法:那就是先排序,再去重。老规矩,它叫代码F:

 1 Array.prototype.clearRepetitionF = function(){
 2     this.sort();
 3     var result = [this[0]];
 4     for(var i=1; i<this.length; i++){
 5         if(this[i] !== result[result.length-1]){
 6             result.push(this[i]);
 7         }
 8     }
 9     return result;
10 } 

  这个先用数组的排序方法sort进行数组元素排序,然后再进行去重工作。这个效率真的会高吗?哎,没学好算法什么的,我的答案也就三个字:不知道。如果你知道欢迎评论区告诉我。

时间: 2024-10-13 00:59:41

JavaScript之数组去重的相关文章

JavaScript实现数组去重方法

一.利用ES6 Set去重(ES6中最常用) function unique (arr) { return Array.from(new Set(arr)) } var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]; console.log(unique(arr)) //[1, "true&quo

使用JavaScript进行数组去重——一种高效的算法

最近比较忙,没时间更新博客,等忙完这阵子会整理一篇使用AngularJS构建一个中型的单页面应用(SPA)的文章,尽情期待!先占个坑. 数组去重的算法有很多种,以下是一种. 思路如下: 定义一个空的对象obj: 循环数组arr,判断obj[arr[i]]是否为false,如果是则将该数组元素放到result中,并且将obj[arr[i]]置为true: obj[arr[0]]肯定为false,因为obj为空,arr[0]将被放到result中,并且obj[arr[0]]被置为true: 循环的过

javascript实现数组去重

数组去重即去掉数组中重复的元素,是web前端工作者在面试过程中和工作中经常会遇到的一个问题,相信一般的方法大家都会,只不过会存在效率差异问题,下面我就来说说我们常用的几种数组去重的方法! 方法1,思路:通过双重循环,每次检测新数组里面是否有该元素,没有就加进去,改方法思路简单,但当数组长度较长时,会非常影响性能!(不推荐使用) function deleteRepeat1(arr) { var newArr = []; for (var i = 0; i < arr.length; i++) {

javascript中数组去重的4种方法

面试前端必须准备的一道问题:怎样去掉Javascript的Array的重复项.在最近面试中,百度.腾讯.盛大等都在面试里出过这个题目.这个问题看起来简单,但其实暗藏杀机. 考的不仅仅是实现这个功能,更能看出你对计算机程序执行的深入理解. 我总共想出了三种算法来实现这个目的: 方法一: Array.prototype.unique1 = function() {     var n = []; //一个新的临时数组     for(var i = 0; i < this.length; i++)

JavaScript (jquery) 数组去重的算法探讨

方法很巧妙 但是要事先知道对应的name或其他属性名称 主键值只适用于已知数据对象进行调用: var arr1 = [{ name: 'C30' }, { name: 'C35' }, { name: 'C40' }, { name: 'C45' }, { name: 'C50' }, { name: 'C60' }, { name: 'C55'}]; //取到strength设定中的列表 var arr2 = [{ name: 'C30' }, { name: 'C35'}]; //取到当前合

原生JavaScript对象数组去重,重构为对象{pro1:[hash], pro02: [hash]}

function unique(objArr) { var result = {}; var proObj = objArr[0]; for(var pro in proObj){ var hash = []; for(var i = 0; i < objArr.length; i++){ var obj = objArr[i]; for(var pros in obj){ if(pros === pro){ var val = obj[pros]; if(!hash[val]){ var va

javaScript数组去重方法

在JAvascript平时项目开发中经常会用到数组去重的操作.这时候就要用到JS数组去重的方法了. demo1: 第一种:JS数组去重操作方法是利用遍历原数组,利用数组的indexOf()方法来来判断新数组b中是否有原数组a中的元素,如果没有的话则在b数组的后面追加上a[i],如果有的话就不执行任何操作,最后可以达到数组去重的操作. 这种方法应该是平时开发中最常用的JS数组去重的方法了,简单又实用. demo2: 第二种去重的方法比较巧妙,是定义一个空对象和一个空数组,在遍历原数组的时候来用原数

javaScript常见的五种数组去重(转载)

JavaScript的数组去重问题在许多面试中都会遇到,现在做个总结 先来建立一个数组 var arr = [1,2,3,3,2,'我','我',34,'我的',NaN,NaN]; ▓▓▓▓▓▓ 第一种 思路:建立一个临时数组,用for循环去依次判断arr中的每个项在临时数组中是否有相同的值,如果没有则将这个值添加到临时数组,如果有相同的值则不添加,最后返回这个临时数组 代码: 1 Array.prototype.removeDuplicate = function(){ 2 var n = [

JS实现字符串去重,数组去重

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>去重</title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 /*数组去重*/ 10 function quch