返回

数组去重的12种方法:一网打尽

IOS

数组去重:高效去除重复元素的 12 种方法

引言

在处理数据时,数组去重是一个常见的任务,它可以极大地提高程序效率和准确性。重复元素的存在会影响程序的性能和数据分析的可靠性。本文将深入探讨 12 种常用的数组去重方法,从最基本的技术到高级的数据结构,全面覆盖不同场景下的解决方案。

1. 双重循环:原始但可靠

双重循环是一种直接且简单的去重方法,它通过嵌套循环逐个比较数组中的元素。当发现重复元素时,它会将重复的元素标记或删除。虽然这种方法的实现简单,但其时间复杂度为 O(n^2),效率较低。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = [];

for (let i = 0; i < arr.length; i++) {
  let isUnique = true;
  for (let j = i + 1; j < arr.length; j++) {
    if (arr[i] === arr[j]) {
      isUnique = false;
      break;
    }
  }
  if (isUnique) {
    uniqueArr.push(arr[i]);
  }
}

console.log(uniqueArr); // [1, 2, 3, 4, 5]

2. for 循环 + findIndex:利用原生数组方法

findIndex() 方法可以查找数组中第一个满足给定条件的元素的索引。利用这一点,我们可以遍历数组,并检查每个元素是否存在于数组中。如果 findIndex() 返回 -1,则表示该元素是唯一的。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = [];

for (let i = 0; i < arr.length; i++) {
  if (arr.findIndex((item) => item === arr[i]) === -1) {
    uniqueArr.push(arr[i]);
  }
}

console.log(uniqueArr); // [1, 2, 3, 4, 5]

3. Set:无序且唯一的集合

Set 数据结构是一个无序且唯一的集合,它可以自动剔除重复元素。添加元素时,它会检查元素是否已经存在,如果存在则忽略。这使得 Set 非常适合去重任务。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueSet = new Set(arr);
const uniqueArr = [...uniqueSet];

console.log(uniqueArr); // [1, 2, 3, 4, 5]

4. Map:键值对形式的去重

Map 数据结构与 Set 类似,但它以键值对的形式存储元素。我们可以将元素作为键,将其添加到 Map 中,如果键已经存在,则忽略。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueMap = new Map();

for (let i = 0; i < arr.length; i++) {
  uniqueMap.set(arr[i], true);
}

const uniqueArr = [...uniqueMap.keys()];

console.log(uniqueArr); // [1, 2, 3, 4, 5]

5. filter:条件筛选去重

filter() 方法可以根据给定的条件从数组中筛选出满足条件的元素,形成一个新的数组。利用这一特性,我们可以过滤掉重复元素,仅保留唯一的元素。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);

console.log(uniqueArr); // [1, 2, 3, 4, 5]

6. indexOf:线性查找去重

indexOf() 方法可以查找数组中某个元素的第一个索引,如果找不到则返回 -1。利用这一特性,我们可以遍历数组,并检查每个元素是否已经存在于数组中。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = [];

for (let i = 0; i < arr.length; i++) {
  if (arr.indexOf(arr[i]) === i) {
    uniqueArr.push(arr[i]);
  }
}

console.log(uniqueArr); // [1, 2, 3, 4, 5]

7. sort + filter:排序后去重

对数组进行排序后,相邻的元素必定相等或不等。我们可以利用这一点,先对数组进行排序,然后使用 filter() 方法过滤掉相邻的重复元素。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const sortedArr = arr.sort((a, b) => a - b);
const uniqueArr = sortedArr.filter((item, index) => item !== sortedArr[index - 1]);

console.log(uniqueArr); // [1, 2, 3, 4, 5]

8. reduce:逐个累加去重

reduce() 方法可以逐个累加数组中的元素,形成一个新的值。我们可以利用这一点,通过 reduce() 累加不重复的元素,形成一个唯一元素的数组。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = arr.reduce((acc, item) => {
  if (!acc.includes(item)) {
    acc.push(item);
  }
  return acc;
}, []);

console.log(uniqueArr); // [1, 2, 3, 4, 5]

9. spread + Set:扩展运算符与 Set 结合

ES6 的扩展运算符 (...) 可以将数组展开为一个个独立的元素。结合 Set 数据结构,我们可以快速剔除重复元素。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = [...new Set(arr)];

console.log(uniqueArr); // [1, 2, 3, 4, 5]

10. 对象键名去重

对象键名具有唯一性,我们可以利用这一点将数组元素作为对象键名,自动剔除重复元素。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueObj = {};

arr.forEach((item) => {
  uniqueObj[item] = true;
});

const uniqueArr = Object.keys(uniqueObj);

console.log(uniqueArr); // [1, 2, 3, 4, 5]

11. 位运算去重

对于二进制数据,我们可以使用位运算符(^) 进行去重。相同元素异或的结果为0,不同元素异或的结果为非0。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueNum = arr.reduce((acc, item) => acc ^ item, 0);
const uniqueArr = [uniqueNum];

console.log(uniqueArr); // [1, 2, 3, 4, 5]

12. 正则表达式去重

正则表达式可以匹配并替换字符串中的特定模式。我们可以利用正则表达式匹配重复的元素,并替换为空字符串。

代码示例:

const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = arr.join(",").replace(/((,)(\d+)\2+(\,))/g, "");

console.log(uniqueArr.split(",")); // [1, 2, 3, 4, 5]

结论

本文介绍了 12 种常用的数组去重方法,涵盖了双重循环、Set、Map、filter、indexOf、sort、reduce、spread、对象键名、位运算、正则表达式等多种技术。每种方法都有其优缺点,开发者应根据实际