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)];//解构赋值
}
复制代码