javascript
数组
array
去重
distinct
unique
恰好前天口试的时刻口试官问到了数组去重的题目,当时有点语塞只想到用了两个轮回检测(实在迷迷糊糊想到了hash的要领做然则由于记得不清不敢说= =!),思绪是检测是不是有元素反复,然后将只涌现一次的元素推入到新数组中,然后返回新数组。然后口试官又问这类要领的时候效力,因而黑线了。so这两天看了一下相干的文章,在这里也总结一下javascript数组去重的要领。
两层轮回检测反复元素法
起首,引见一下人人都邑想到的两层轮回的demo,以下例:
function distinct(arr) {
var ret = [],
length = arr.length;
for(var i = 0;i < length; i++){
for(j = i+1; j<length;j++){
if(arr[i] === arr[j]){
j = ++i;
}
}
ret.push(arr[i]);
}
return ret;
}
var arra = [1,2,3,4,4,1,1,2,1,1,1];
distinct(arra); //返回[3,4,2,1]
<!–more–>
如上的代码完成是轻松易得的,思绪以下:
起首外层轮回比遍历全部数组
内层轮回婚配是不是有值反复
a.如推断有雷同元素则自增i变量,跳出i的轮回 b.如推断无时则将无相等值的元素推入到ret数组中
3.返回ret。
长处:便利易懂,大多数顺序员能想到。
瑕玷:很明显时候斲丧太高,两层轮回时候斲丧太多,时候的斲丧为O(n^2^),在举行大批数据处置惩罚时会斲丧大批资本。而且该要领没法处置惩罚字符和数组,以下例:
var arr = [1,23,4,5,6,7,'1',22,3,1,2];
distinct(arr); //返回[23, 4, 5, 6, 7, "1", 22, 3, 1, 2]
所以我们能够最先斟酌一些别的要领优化数组去重:
sort重排数组去除反复元素索引法(!每个浏览器中的sort函数的排序要领并不一样,所以完成效果能够会有差别,经测试在chrome下测试别的数组完成会涌现题目)
这类要领就是先讲原数组运用sort要领将数组重排,以取得将雷同元素为相邻位的一个新数组。该要领以下:
function distinct(arr){
var self = arr;
list = self.concat().sort();
list.sort(function(a, b){
if(a === b){
var ind = self.indexOf(a);
self.splice(ind, 1);
}
});
return self;
}
var arra = [1,2,3,3,1,1,1,'1'];
var arr = distinct(arra); //返回的数组为[2,3,1,'1']
一样的,在运用这类要领的重排的时刻,依然会有肯定的资本斲丧,在sort()函数中回调函数是运用的冒泡排序,而冒泡排序的效力并不高。然则运用这类要领的效力依然比上一种要领的效力高,由于在此例中只涌现了一次轮回遍历。
长处:顺序简约,效力较高。
瑕玷:1.依然没法处理数字1和字符’1’的去除。2.依靠indexOf要领,我们晓得在IE6~8中并未支撑indexOf()要领。
所以我们还要做一些兼容性的处置惩罚。以下:
var indexOf = [].indexOf ?
function indexOf(arr, item){
return arr.indexOf(item);
}:
function indexOf(arr, item){
for(var i = 0; i < arr.length; i++){
if(arr[i] === item){
retrun i;
}
}
return -1;
}
function distinct(arr){
var self = arr;
list = self.concat().sort();
list.sort(function(a, b){
if(a === b){
var ind = self.indexOf(arr, a);
self.splice(ind, 1);
}
});
return self;
}
将数组元素值存为对象的属性
function distinct(arr) {
var ret = [],
json = {},
length = arr.length;
for(var i = 0; i < length; i++){
var val = arr[i];
if(!json[val]){
json[val] = 1;
ret.push(val);
}
}
return ret;
}
var arra = [1,2,3,5,7,1,2,'1'];
以上要领越发的简约,而且也能在本来的基础上辨别字符‘1’和数字1的区分。
在此例中思绪以下:
1.轮回遍历每个元素
2.检测在json对象中是不是含遍历到的元素的值
a: 假如是则跳过
b: 假如否存入json对象中该属性名的值设为1
3.将存入对象了元素的值推入到新数组中,返回新数组。
总结,实在数组去重不过就是推断一个元素在数组中是不是有反复的值。优化也是一向转变剖断元素是不是反复的一些技能,如例1中是遍历数组,例2是重排数组取得索引,例3则别开生面将元素的值作为对象的属性。
参考自:
从 JavaScript 数组去重谈机能优化
也谈javascript数组去重
js数组去重
感谢@飞的更高 指出的题目
同步于个人博客:http://penouc.com