阅读本文需要了解 “高阶函数”。 请参考:http://blog.csdn.net/wershest/article/details/71036581
1. 最直观,但比较naive的算法:
uniqueArray = a.filter(function(item, pos) {
return a.indexOf(item) == pos;
});
遍历数组,对于每一个值,查找它在数组中出现的第一个索引(indexOf函数),如果与当前pos不同,则该值有重复。
稍微优化一下,避免在filter的函数中使用外部变量:
uniqueArray = a.filter(function(item, pos, self) {
return self.indexOf(item) == pos;
});
对于大型数组,这种算法的性能较差(n*n)。
2. 使用hashtable
function uniq(a) {
var seen = {};
return a.filter(function(item) {
return seen.hasOwnProperty(item) ? false : (seen[item] = true);
});
}
该算法的效率比较好,复杂度是线形的。但它有两个缺点:
1. 在js中hash的key只能是string,它不能区分 1 和 "1"。 uniq([1, "1"]) 返回 [1]。
2. 基于相同的原因,该算法不支持元素是object数组。
如果数组元素都是Number或者String,推荐使用这个算法。
3. 两全其美的办法
综合以上两种算法,遇到哪种类型就用哪种方法:
function uniq(a) {
var prims = {"boolean":{}, "number":{}, "string":{}}, objs = [];
return a.filter(function(item) {
var type = typeof item;
if(type in prims)
return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true);
else
return objs.indexOf(item) >= 0 ? false : objs.push(item);
});
}
4. 先排序
先排序,再遍历,如果当前元素与前一个元素相同,则删除。
function uniq(a) {
return a.sort().filter(function(item, pos, ary) {
return !pos || item != ary[pos - 1];
});
}
这种方法也不适用于 Object 类型的数组,因为,sort函数认为所有的object都相等。
5. ES6 提供了 Set
function uniq(a) {
return Array.from(new Set(a));
}
参考文档: