我只想说,我如果不看这篇文章,我是不会知道去重还有这么多种方法的。同时看别人代码优化,很有启发,开拓新思路哇。
方法
双重循环
兼容性好
function unique(array) {
// res用来存储结果
var res = [];
for (var i = 0, arrayLen = array.length; i < arrayLen; i++) {
for (var j = 0, resLen = res.length; j < resLen; j++ ) {
if (array[i] === res[j]) {
break;
}
}
// 如果array[i]是唯一的,那么执行完循环,j等于resLen
if (j === resLen) {
res.push(array[i])
}
}
return res;
}
indexOf优化
底层使用===判断是否相等
function unique(array) {
var res = [];
for (var i = 0, len = array.length; i < len; i++) {
var current = array[i];
if (res.indexOf(current) === -1) {
res.push(current)
}
}
return res;
}
排序去重
- var sortedArray = array.concat().sort();先concat的目的是拷贝一份数组。
- 如果我们对一个已经排好序的数组去重,这种方法效率肯定高于使用 indexOf。
function unique(array) { var res = []; var sortedArray = array.concat().sort(); var seen; for (var i = 0, len = sortedArray.length; i < len; i++) { // 如果是第一个元素或者相邻的元素不相同 if (!i || seen !== sortedArray[i]) { res.push(sortedArray[i]) } seen = sortedArray[i]; } return res; }
看看大神怎么优化性能的
这个方法是最想好好理解的,可以说是开拓了一种新思路。参数传递方法的妙用哇。
新需求:字母的大小写视为一致,比如'a'和'A',保留一个就可以了!
// iteratee 英文释义:迭代 重复
function unique(array, isSorted, iteratee) {
var res = [];
var seen = [];
for (var i = 0, len = array.length; i < len; i++) {
var value = array[i];
var computed = iteratee ? iteratee(value, i, array) : value;
if (isSorted) {
if (!i || seen !== value) {
res.push(value)
}
seen = value;
}
else if (iteratee) {
if (seen.indexOf(computed) === -1) {
seen.push(computed);
res.push(value);
}
}
else if (res.indexOf(value) === -1) {
res.push(value);
}
}
return res;
}
console.log(unique(array3, false, function(item){
return typeof item == 'string' ? item.toLowerCase() : item
}));
filter方法
function unique(array) {
return array.concat().sort().filter(function(item, index, array){
return !index || item !== array[index - 1]
})
}
Object 键值对
function unique(array) {
var obj = {};
return array.filter(function(item, index, array){
return obj.hasOwnProperty(item) ? false : (obj[item] = true)
})
}
上面代码看似没有问题,但是将上和'1'判断为相等的了,因为对象的键值只能是字符串,所以我们可以使用 typeof item + item 拼成字符串作为 key 值来避免这个问题。修改的代码如下:
function unique(array) {
var obj = {};
return array.filter(function(item, index, array){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
ES6
随着 ES6 的到来,去重的方法又有了进展,比如我们可以使用 Set 和 Map 数据结构,以 Set 为例,ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
// 一
function unique(array) {
return Array.from(new Set(array));
}
// 二
function unique(array) {
return [...new Set(array)];
}
// 三
var unique = (a) => [...new Set(a)]
// 四
function unique (arr) {
const seen = new Map()
return arr.filter((a) => !seen.has(a) && seen.set(a, 1))
}