为了账号安全,请及时绑定邮箱和手机立即绑定

几种常用的数组去重的方法及优缺点

标签:
JavaScript
方案一:数组双循环比较
  • 依次拿数组的每一项(排除最后一项:后面没有需要比较的内容了)
  • 和当前拿出项后面的每一项进行比较
  • 如果发现重复,把这个重复项再原有数组中删除(splice)

此方法特别浪费性能

var ary=[1,2,1,5,4,3,2,6];
for(var i=0;i<ary.length-1;i++){
	var item = ary[i]
	// item:依次拿出每一项
	// i:当前项的索引
	//和当前项的后一项比较:起始索引应该是i+1,k<ary.length找到末尾依次比较
		for(var k = i+1; k<ary.length;k++){
		// ary[k]:后面需要与当前项比较的值
		if(item==ary[k]){
		//相等,即重复项,在原有数组中删除
			ary.splice(k,1)
			//这样做会导致数组塌陷问题:删除重复项后,数组的length会发生改变,此时k累加,拿出来的结果就回跳过一位
			k--;//删除后先减减,再加加,相当于没加没减
		}
	}
}
console.log(ary);  //[1, 2, 5, 4, 3, 6]
方案二:基于对象键值对方式去重
  • 基于对象的属性名不能重复,实现高性能的数组去重
  • 创建空对象
  • 依次遍历数组中的每一项,把每一项值,当做对象的属性名和属性值存起来
  • 存储之前判断对象中是否已经存在相同属性名(是否重复),把当前重复项在数组中移除
    var ary=[1,2,1,5,4,3,2,6],
	    obj = {}
    for(var i=0;i<ary.length;i++){
		var item = ary[i]
		// item:依次拿出每一项
		// i:当前项的索引
		//存储之前需要判断,是否已存在这个属性名
		if(typeof obj[item]=='undefined'){
			//属性名=属性值
			obj[item] = item
		}else{
			//删除方法一
			ary.splice(i,1);//删除之后索引都需要从新计算,耗性能
			i--;
			
			//删除方法二
			//1. 把当前重复项用最后一项替换
			//2. 删除最后一项,length还是减了1
			//3.i--继续匹配当前索引项
			ary[i] = ary[ary.length-1];
			ary.length--;
			i--;
		}
	}
	console.log(ary);  //[1, 2, 5, 4, 3, 6]
方案三:利用set方法去重

如不考虑兼容问题,可利用es6语法,set()来实现去重

	var ary=[1,2,1,5,4,3,2,6],
		newAry=[];
		newAry = Array.from(new Set(ary))
		console.log(newAry)// [1, 2, 5, 4, 3, 6]
方案三:封装数组去重方法
	var ary=[1,2,1,5,4,3,2,6],
	function unique(ary){
		var obj={};
		//利用对象属性名不重复的原则,把数组每个的值作为属性名和属性值存到对象中,每次存储之前验证当前对象中是否已经存在(in/hasOwnProperty/属性值不是undefined),如果存在这个属性说明是重复项,那就把原有数组中移除;如果不存在,继续存储
		for(var i = 0; i <ary.length;i++){
            var item = ary[i];
            if(obj.hasOwnProperty(item)){
                ary.splice(i,1); //方法一
                /*
                *优化-:
                *不适用splice删除(删除当前项,后面索引向前移,性能消耗大,)
                * 解决:把最后一项替换当前项,再把最后一项删除(会改变原有数组顺序)
                */
                
                //方法二
                ary[i] = ary[ary.length-1];
                ary.pop();
                
                i--;
                continue;
            }
            obj[item] = item;
        }
        obj=null;  //obj不用了,要释放掉;
        return ary;
	}
方案四:基于内置类的原型扩展方法,供它的实例调取使用
var ary=[1,2,1,5,4,3,2,6]
//属性名命名时,可以加前缀,防止属性名冲突
Array.prototype.myUnique = function myUnique(){
	//方法中的this一般都是当前类的实例(我们要操作的数组)
	//操作this相当于操作ary,方法执行会改变原有数组
	var obj={};
	for(var i = 0; i <this.length;i++){
        var item = this[i];
        obj.hasOwnProperty(item) ? (this[i] = this[this.length - 1],this.length--,i--) : obj[item] =item;
        obj = null;
        return this;
    }
}
var max = ary.myUnique().ary.sort(function(a,b){
	return a- b;
}).pop();
数组排序
var ary=[1,2,1,5,4,3,2,6]
//sort是array.prototype内置的属性,而ary是一个实例,可以基于_proto_找到原型上的方法,然后d
ary.sort(function(a,b){
	return a- b;
}).reverse().slice(2,7).join('+').split('+').pop()//已经不是数组了
//js中的链式写法:保证每一个方法执行返回的结果依然是当前类的实例,这样就可以继续调取方法使用了
点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消