如何消除一个数组里面重复的元素?

在日常开发中,我们可能会遇到去重问题,这篇文章就是为了解决这个问题而写的。

为了方便使用,我们可以直接把封装的去重函数直接加入到数组的prototype中。

方法一:

Array.prototype.clearRepeat = function() {

var arr = []; //定义一个临时数组

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

//通过遍历判断当前数组下标为i的元素是否保存到临时数组中

//如果保存,则跳过,否则保存到临时数组

if(arr.indexOf(this[i]) == -1) {

arr.push(this[i]);

}

}

return arr;

};

var test = [1, 6, 8, 8, 9, 9, 9, "a", "a"];

test.clearRepeat();    //结果为[1, 6, 8, 9, "a"]

方法二:

Array.prototype.clearRepeat = function() {

var arr = [this[0]]; //直接定义结果数组

for(var i = 1; i < this.length; i++) { //从第二项开始遍历当前数组

//对元素进行判断:

//如果当前数组元素在此数组中第一次出现的位置不是i

//则第i项是重复的,否则直接存入结果数组

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

arr.push(this[i]);

}

}

return arr;

};

var test = [1, 6, 8, 8, 9, 9, 9, "a", "a"];

test.clearRepeat();    //结果为[1, 6, 8, 9, "a"]

上面两种方法不推荐使用,因为indexOf()这个函数在执行的时候每次都会遍历一次数组,对性能影响比较大。比较适合小数据量的数组。

方法三:

Array.prototype.clearRepeat = function() {

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

var arr = []; //定义一个临时数组

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

//对元素进行判断是否存在表中,如存在则跳过,否则存入临时数组

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

h[this[i]] = true; //存入hash表

arr.push(this[i]);

}

}

return arr;

};

var test = [1, 6, 8, 8, 9, 9, 9, "a", "a"];

test.clearRepeat();    //结果为[1, 6, 8, 9, "a"]

上面这种方法使用的是hash表,把已经出现过的元素通过下标形式写入一个Object中,下标的引用要比数组的indexOf()方法搜索节省时间。

顺便补充下hash表的知识:

哈希表也叫散列表,是根据关键码值(key, value)而进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,以加快查找速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表

关于hash表的详细知识请点击这里

通过测试发现上面这种方法存在一种缺陷,那就是当数组中同时出现类似于1和“1”这样的元素时,会把“1”这样的元素被去重。

var test = [1, 6, 8, 8, 9, 9, 9, "a", "a", "1"];

test.clearRepeat();    //结果为[1, 6, 8, 9, "a"],正确的应该为[1, 6, 8, 9, "a","1"]

查阅资料发现原因是因为:

作为下标在转换后会变成字符串,那么对于1和“1”这样不同类型的值会对应到同一个下标而被去重。

修改后的代码:

Array.prototype.clearRepeat = function() {

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

var arr = []; //定义一个临时数组

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

//对元素进行判断是否存在表中,如存在则跳过,否则存入临时数组

var type = typeof this[i];

if(!h[this[i] + type]) {

h[this[i] + type] = true;

arr.push(this[i]);

}

}

return arr;

};

var test = [1, 6, 8, 8, 9, 9, 9, "a", "a", "1"];

test.clearRepeat();    //结果为[1, 6, 8, 9, "a", "1"]

方法四:

Array.prototype.clearRepeat = function() {

this.sort(); //数组排序

var arr = [this[0]]; //定义结果数组

for(var i = 1; i < this.length; i++) { //从第二项开始遍历当前数组

//判断两个相邻元素是否相等,如果相等说明数据重复,否则将元素写入结果数组

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

arr.push(this[i]);

}

}

return arr;

};

var test = [1, 6, 8, 8, 9, 9, 9, "a", "a"];

test.clearRepeat();    //结果为[1, 6, 8, 9, "a"]

上面这种方法先将数组排序,然后比较相邻两个元素是否相等,若相等说明重复。数组排序采用的原生sort()。

关于数组排序方法请点击这里

上面四种方法的优劣和性能读者可以自行去测试。

如果你在本文中发现错误或者有异议的地方,可以在评论区留言,谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容