如何返回一个数组中的重复元素?
这个问题好像等同于:如何返回一个数组中被删除的重复元素?
我们换个测试案例,立刻就能看出问题所在。
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 test var 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还是对象。
如果你熟悉这些对象之间的不同,你就可以自由穿梭于代码世界,逢山开路,遇水搭桥。