如何返回一个数组中的重复元素?
这个问题好像等同于:如何返回一个数组中被删除的重复元素?
我们换个测试案例,立刻就能看出问题所在。
| Array.prototype.distinct = function() {var ret = [];
 for (var i = 0; i < this.length; i++) {
 for (var j = i+1; j < this.length; j++) {
 if (this[i] === this[j]) {
 ret.push(this.splice(j, 1)[0]);
 
 }
 }
 }
 }
 
 
 console.log(['a','b','a','d','b','a','e'].distinct());
 
 | 
居然返回了两个a,问题出在哪里呢?
第1个a和第二个a比较后,相同,所以把第二个a放入新数组,
当第1个a和第三个a比较后,也相同,所以把第三个a也放入新数组。
所以你看到了返回结果里有两个a。
我们来看下原来的数组和返回的数组有什么不同?
| //for testvar arr=['a','b','a','d','b','a','e'];
 console.log(arr.distinct()); //["a", "a", "b"]
 console.log(arr); //["a", "b", "d", "e"]
 
 | 
也就是说原来的数组里面的重复元素已经去除了,但返回的数组里面包含有重复元素。
也就说放入元素到新数组前必须要先判断下,数组是否已经包含有此元素。
代码改进后如下:
| Array.prototype.distinct=function () {var ret = [];
 for (var i = 0; i < this.length; i++) {
 for (var j = i+1; j < this.length;j++) {
 if (this[i] == this[j]) {
 var value=this.splice(j, 1)[0];
 if(ret.indexOf(value)==-1){
 ret.push(value);
 }
 }
 }
 }
 return ret;
 }
 
 var arr=['a','b','a','d','b','a','e'];
 console.log(arr.distinct());
 console.log(arr);
 
 | 
如何去掉一个数组中的重复元素?
基于上面的代码:如何返回一个数组中的重复元素,我们可以快速写出:
| Array.prototype.uniq=function () {var ret = [];
 for (var i = 0; i < this.length; i++) {
 for (var j = i+1; j < this.length;j++) {
 if (this[i] == this[j]) {
 this.splice(j, 1);
 }
 }
 }
 return this;
 }
 
 var arr=['a','b','a','d','b','a','e'];
 console.log(arr.uniq());
 
 | 
双重for循环在数据量大时会有性能问题,有没有一种简便的方法呢?
回到我们前面的代码:如何返回一个数组中的重复元素。
为了规避返回的数组中有重复元素,我们做了一个判断。
我们都知道object的key是唯一的。
举例:
| var obj={name:'huluoyang',name:'google'};console.log(obj);
 
 | 
所以我们可以利用object的key是唯一的特性,
把数组的元素作为object的key保存起来,这样重复元素就自动被干掉了。
代码如下:
| Array.prototype.uniq=function(){var temp=[];
 var obj={};
 for(var i=0;i<this.length;i++){
 obj[this[i]]=true;
 }
 for(i of obj){
 temp.push(i);
 }
 return temp;
 }
 var arr=['a','b','a','d','b','a','e'];
 console.log(arr.uniq());
 
 | 
实现原理:数组和对象的双向转化
怎么样,是不是觉得js很好玩啊,字符串是对象,数组也是对象,object还是对象。
如果你熟悉这些对象之间的不同,你就可以自由穿梭于代码世界,逢山开路,遇水搭桥。