数据处理 | 数组去重(13种)

灵魂拷问:数组去重的方式你知道多少呢?

方式1:遍历 + indexOf

1
2
3
4
5
6
7
8
9
10
11
12
13
function fn(arr) {
let res = [];
for (let item of arr) {
if (res.indexOf(item) === -1) {
res.push(item);
}
};
return res;
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式2: 遍历 + findIndex

1
2
3
4
5
6
7
8
9
10
11
12
13
function fn(arr) {
let res = [];
for (let item of arr) {
if (res.findIndex(i => i === item) === -1) {
res.push(item);
}
};
return res;
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式3: 遍历 + find

1
2
3
4
5
6
7
8
9
10
11
12
13
function fn(arr) {
let res = [];
for (let item of arr) {
if (!res.find(i => i === item)) {
res.push(item);
}
};
return res;
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式4: 遍历 + includes

1
2
3
4
5
6
7
8
9
10
11
12
13
function fn(arr) {
let res = [];
for (let item of arr) {
if (!res.includes(item)) {
res.push(item);
}
};
return res;
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式5:forEach + 重复方式1234

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function fn(arr) {
let res = [];
arr.forEach((item) => {
if (res.indexOf(item) === -1) {
res.push(item);
}
});
return res;
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]


// 其他的换汤不换药,不写了

方式6:reduce + concat或者扩展运算符合并数组+重复方式1234

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function fn(arr) {
return arr.reduce((acc, cur) => {
if (acc.indexOf(cur) === -1) {
acc = acc.concat(cur);
// 或者是
// acc = [...acc, ...cur];
};
return acc;
}, [])
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]


// 其他的换汤不换药,不写了

方式7: filter + indexOf

利用indexOf是返回第一个搜索到的index,来过滤非第一个搜索到的index的元素

1
2
3
4
5
6
7
function fn(arr) {
return arr.filter((item, index) => arr.indexOf(item) === index);
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式8: Set + 扩展运算符

最快的方式,一行搞定

利用:

  1. Set()中没有重复元素
  2. 扩展运算符:任何定义了遍历器接口的对象,都可以用扩展运算符转为数组
1
2
3
4
5
6
7
function fn(arr) {
return [...new Set(arr)];
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式9: Map + keys() + 扩展运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fn(arr) {
let m = new Map();
for (let item of arr) {
if (!m.has(item)) {
m.set(item, true); // 值随便指定无所谓
}
};

return [...m.keys()];
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式10:嵌套循环 + splice去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function fn(arr) {
for (let i = 0; i < arr.length ; i++) {
for (let j = i+1; j< arr.length; j++) {
if (arr[j] === arr[i]) {
arr.splice(j, 1);
j--;
}
}
};
return arr;
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式11:sort() + 嵌套循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fn(arr) {
arr.sort((a, b) => a - b);
let res = [arr[0]];
for (let i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i-1]) {
res.push(arr[i]);
}
}
return res;
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 4, 5, 6, 7]

方式12:hasOwnProperty

1
2
3
4
5
6
7
8
9
10
function fn(arr) {
let m = {};
return arr.filter(function(item, index, arr){
return m.hasOwnProperty(typeof item + item) ? false : (m[typeof item + item] = true)
})
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 5, 6, 7, 4]

方式13: 递归去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function fn(arr) {
arr.sort((a,b) => a- b);

function bar(index) {
if (index >= 1) {
if (arr[index] === arr[index-1]) {
arr.splice(index, 1);
}
bar(index-1);
}
}
bar(arr.length-1);
return arr;
}

// test
const arr = [1,2,3,1,2,3,5,6,7,4,3,2,6,6];
console.log(fn(arr)); // [1, 2, 3, 4, 5, 6, 7]