数组去重方法

281 阅读2分钟

1. 使用原生的filter和indexOf来进行过滤和筛选。

var filtered = data.filter(function(item, index){
	return data.indexOf(item) === index;
});

使用filter的第三个参数绑定this的值

var filtered2 = data.filter(function(item, index, self){
	return self.indexOf(item) === index;
});

2. 使用hash表,单独使用一个object来建立hash表,从单独的obj的属性是否存在来判断。如果存在,那就将该属性设置为true;

要点:使用hasOwnProperty()来进行判断,并且使用双目运算符。

function unique(a){
	var oSeen = {};
	return a.filter(function(item, index){
		return oSeen.hasOwnProperty(item) ? false : oSeen[item] = true;
	})
}

3. 使用hash表,并将每一个item的数据类型进行分类,以便应对obj的key无论number、或者是string类型都是同一个,无法识别的问题。

要点:使用typeOf将item分类成为基础原始类型和object类型,来进行不同的判断。 针对基础类型,使用hash表索引,在不同类型里面存储不同的key,不会导致number和string 覆盖的问题。 针对object类型,直接使用indexOf来进行标识key,检索比较

function unique(a){
	var oPrims = {"boolean": {}, "number": {}, "string": {}};
	var aObj = [];
	return a.filter(function(item, index){
		var type = typeof item;
		if(type in oPrims){
			return oPrims[type].hasOwnProperty(item) ? false : (oPrims[type][item] = true);
		}else{
    aObjs.indexOf(item) >= 0 ? false : aObjs.push(item);
			//a.indexOf(item) === index;
		}
	})
}

为unique添加一个处理函数 比如数组的某些项不能直接进行比较的

function uniqueBy(a, dealFn){
	var oSeen = {};
	return a.filter(function(item, index){
		var transKey = dealFn(item);
		return oSeen.hasOwnProperty(transKey) ? false : (oSeen[transKey] = true);
	})
}
function addPrefix(item){
 return item + 'yes';
}

此处oSeen还可以使用Set类型来判断

function uniqBy(a, key) {
    var seen = new Set();
    return a.filter(item => {
        var k = key(item);
        return seen.has(k) ? false : seen.add(k);
    });
}

4. 对原数组使用sort之后再进行比较(将前一个和后一个比较)

要点:sort默认使用空参数,不制定规则也可。自定义规则还没有试过。sort对于object类型的可能无效。 sort默认的就是以字符串的顺序来排的,会以string类型的来排。比如:"12",1, 4 -----> 1,12 4

function unique3(a){
	return a.sort().filter(function(item, index){
		return item != a[index - 1];
	});
}

5. 使用ES6的set,但是set构建的是一个对象,因此需要Array.from(obj)来进行转换

要点: set类型是一种不允许重复类型的数据结构;

function uniqueSet(a){
	//return Array.from(new Set(a));
	return [...new Set(a)];//解构赋值
}