首先,我想到的是另建一个结果数组,用来存储原始数组中不重复的数据。遍历原始数组依次跟结果数组中的元素进行比较,检测是否重复。于是乎,我写出了如下代码A:
Array.prototype.clearRepetitionA = function(){ var result = []; var isRepetition; for(var i=0; i<this.length; i++){ isRepetition = false; for(var j=0; j<result.length; j++){ if(this[i] === result[j]){ isRepetition = true; break; } } if(!isRepetition){ result.push(this[i]); } } return result; }
写完之后,忽然想起来前几天刚看的ECMAScript 5中的数组方法indexOf 可以检索数组元素。于是我又使用indexOf 方法替代了第二层循环,写出了如下代码B:
Array.prototype.clearRepetitionB = function(){ var result = []; for(var i=0; i<this.length; i++){ if(result.indexOf(this[i]) == -1){ result.push(this[i]); } } return result; }
代码一下子从17行变成了9行了,简洁多了。高三数学大题解法一般都不止一种的啊,然后我就继续再想其他方法了。indexOf 方法的意思是搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引,没有找到就返回 -1 ,第一个参数就是要搜索的值,第二个参数可选:它指定数组中的一个索引,从那里开始搜索,如果省略这个参数,则从头搜索。思维一发散,想到了前面方法都是检测值是否重复的,现在有了indexOf 方法不就可以根据检测到的每个元素的第一次出现时的索引和这个元素自身的索引值比较相等来判断是否重复嘛。所以,我又写出了代码C:
Array.prototype.clearRepetitionC = function(){ var result = [this[0]]; for(var i=1; i<this.length; i++){ if(this.indexOf(this[i]) == i){ result.push(this[i]); } } return result; }
写完这个,又继续想了想,实在是想不出其他方法了,这三个方法都是很基础的方法。于是,我就去对照答案,检验自己了。一看答案,发现自己还是真实太弱了,简单的问题还是有些奇思妙想的。下面不是自己想的了,就不再说太多我的心路历程了。废话不多说,直接上经典的答案+解析了。
首先,先说一个算法中经常说的以空间换时间的解法,保持队形,我们就叫它代码D吧:
Array.prototype.clearRepetitionD = function(){ var result = []; var obj = {}; var key,type; for(var i=0; i<this.length; i++){ key = this[i]; type = typeof key; if(!obj[key]){ obj[key] = [type]; result.push(key); }else if(obj[key].indexOf(type)){ obj[key].push(type); result.push(key); } } return result; }
这个方法中在遍历原始数组时用一个对象 obj 的属性来保存原始数组中元素的值。同时这个属性的值是一个数组,用来存储这个属性的类型,这一点可以把原始数组中类似数字1元素和字符串‘1'的元素区分开。这个方法通过额外构建一个对象的方式降低了上面三种方法中indexOf方法所花费的时间,可以说较为高效吧。
如果你已经满足于上面所说的以空间换时间的高效方法而不继续看下去的话,那就大错特错了,好戏总在后头嘛。现在好戏开场,毫无疑问,就是代码E了:
Array.prototype.clearRepetitionE = function(){ var result = []; for(var i=0; i<this.length; i++){ for(var j=i+1; j<this.length; j++){ if(this[i] === this[j]){ j = ++i; } } result.push(this[i]); } return result; }
代码D以空间换时间,感觉也就一般般。那么代码E呢?这代码是错误的吧,这个真的能去重吗?是的,起初我都没看懂这代码,看了解析后又看了一遍之后才明白过来。那么,没看懂的看官也要认真的看解析了:第一层从前往后遍历原始数组,第二层循环是检测每个元素是否跟它之后的元素重复,如果它之后有重复元素则跳过它;如果这个元素之后所有元素都跟他不重复了,则把它添加到结果数组中。这个方法实现思路就是:获取无重复的最右一值添加到结果数组中,这个跟第一种方法相比也优化了第二层的循环,效率要比它高,不过这个方法的结果数组中元素的顺序跟原始数组中元素的顺序不一样了。
看完了代码E解析的你是不是已经伸出了大拇指、投放出了敬佩的目光呢?(这些鲜花和荣誉别给我,应该给写这个方法的大神去)。下面再说最后一个方法:那就是先排序,再去重。老规矩,它叫代码F:
Array.prototype.clearRepetitionF = function(){ this.sort(); var result = [this[0]]; for(var i=1; i<this.length; i++){ if(this[i] !== result[result.length-1]){ result.push(this[i]); } } return result; }
这个先用数组的排序方法sort进行数组元素排序,然后再进行去重工作。
以上就是对javascript数组去重问题的一步步研究,不断改进代码,总共分享了六段代码,希望大家认真学习,能够有所收获。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。