数组去重的几种方法
在 JavaScript 中,数组去重是一个常见的需求。下面我们来探讨几种常用的数组去重方法。
双重 for 循环
使用双重 for 循环是一种比较直观的数组去重方法。外层循环遍历原数组的每个元素,内层循环检查该元素是否已经存在于新数组中,如果不存在就添加到新数组。
function uniqueArray(arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
let isDuplicate = false;
for (let j = 0; j < result.length; j++) {
if (arr[i] === result[j]) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
result.push(arr[i]);
}
}
return result;
}
let arr = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 0, 0];
console.log(uniqueArray(arr));
这种方法虽然直观,但时间复杂度较高,为 O(n^2)。当数组长度较大时,效率会比较低。
filter + indexOf
利用 filter
方法和 indexOf
方法也可以实现数组去重。filter
会遍历数组的每个元素,对于每个元素,判断它在原数组中第一次出现的位置是否等于当前位置,如果是则保留,否则过滤掉。
function uniqueArray(arr) {
return arr.filter((item, index) => arr.indexOf(item) === index);
}
let arr = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 0, 0];
console.log(uniqueArray(arr));
这种方法简洁易懂,时间复杂度为 O(n)。
forEach + includes
使用 forEach
遍历原数组,对于每个元素,用 includes
判断它是否已经存在于新数组中,如果不存在就添加进去。
function uniqueArray(arr) {
let result = [];
arr.forEach((item) => {
if (!result.includes(item)) {
result.push(item);
}
});
return result;
}
let arr = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 0, 0];
console.log(uniqueArray(arr));
这种方法和使用 indexOf 类似,时间复杂度也是 O(n)。
先 sort 再遍历
先对原数组进行排序,这样相同的元素就会被排在一起。然后遍历排序后的数组,把不重复的元素放入新数组中。
function uniqueArray(arr) {
arr.sort();
let result = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] !== arr[i + 1]) {
result.push(arr[i]);
}
}
return result;
}
let arr = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 0, 0];
console.log(uniqueArray(arr));
这种方法的时间复杂度取决于排序算法,如果使用快速排序,平均时间复杂度为 O(nlogn)。
另一种写法是将当前元素与结果数组的最后一个元素比较:
function uniqueArray(arr) {
arr.sort();
let result = [];
for (let item of arr) {
if (item !== result[result.length - 1]) {
result.push(item);
}
}
return result;
}
let arr = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 0, 0];
console.log(uniqueArray(arr));
sort + reduce
先对原数组进行排序,再利用 reduce
方法遍历数组,把不重复的元素累加到结果数组中。
function uniqueArray(arr) {
arr.sort();
return arr.reduce((prev, cur) => {
if (cur !== prev[prev.length - 1]) {
prev.push(cur);
}
return prev;
}, []);
}
let arr = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 0, 0];
console.log(uniqueArray(arr));
这种方法将遍历和结果累加放在一起,代码简洁,时间复杂度与先 sort 再遍历一致。
Set
利用 ES6 新增的 Set 数据结构也可以很方便地实现数组去重。Set 可以保证内部元素的唯一性。
function uniqueArray(arr) {
return [...new Set(arr)];
}
let arr = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 0, 0];
console.log(uniqueArray(arr));
将数组传入 Set 构造函数中,就可以得到一个去重后的 Set 对象。再利用扩展运算符将 Set 转为数组即可。
这种方法代码最简洁,时间复杂度为 O(n)。
Object 键值对
利用 Object 的键值对特性也可以实现数组去重。将数组元素作为 Object 的键,值设为任意。由于 Object 的键不能重复,所以最终得到的就是一个去重后的对象。
function uniqueArray(arr) {
let obj = {};
arr.forEach((item) => {
obj[item] = 0;
});
return Object.keys(obj);
}
let arr = [1, 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 0, 0];
console.log(uniqueArray(arr));
遍历数组,将元素作为键放入对象中。最后通过 Object.keys
取出对象的键即可得到去重后的数组。
这种方法的时间复杂度为 O(n),但结果数组为字符串数组。如果需要转换为数字数组,还需要进行一次类型转换。