1.利用ES6的Set
Set是一种新的数据结构,它的成员具有唯一性。可以将数组转换为Set,再转换回数组来实现去重。
let arr = [1, 2, 2, 3, 4, 4];
let uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4]
这种方法非常简洁,而且效率较高。它适用于数组元素是基本数据类型(如数字、字符串、布尔值)或者是引用数据类型(对象、数组等)且希望根据引用是否相同来去重的情况。
2. 利用filter和indexOf
可以通过 filter 方法遍历数组,只保留第一个出现的元素,即索引为 0 的元素。
let arr = [1, 2, 2, 3, 4, 4];
let uniqueArr = arr.filter((element, index) => {
return arr.indexOf(element) === index;
});
console.log(uniqueArr); // [1, 2, 3, 4]
这种方法的原理是 indexOf 返回元素在数组中第一次出现的位置,如果当前元素的索引和 indexOf 返回的索引相同,说明这个元素是第一次出现,就将其保留下来。不过这种方法对于包含对象等引用数据类型的数组,如果对象内容相同但引用不同,可能无法达到理想的去重效果。
3. 利用双重循环(传统方法)
这种方法比较直观,但效率相对较低。外层循环遍历数组,内层循环检查当前元素后面的元素是否与之重复,若重复则删除。
let arr = [1, 2, 2, 3, 4, 4];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1);
j--;
}
}
}
console.log(arr); // [1, 2, 3, 4]
在这里,当发现重复元素时,使用 splice 方法将其删除,并且需要将内层循环的索引 j 减 1 ,因为删除元素后数组长度和元素索引都发生了变化,否则可能会跳过一些元素。
4. 利用对象的属性来记录元素是否出现过(适用于基本数据类型)
创建一个空对象,遍历数组,将数组元素作为对象的属性名,属性值可以是任意值(比如 true )。如果对象中不存在该属性,就将元素添加到新数组中,并在对象中记录该属性;如果已经存在,则说明元素重复,跳过该元素。
let arr = [1, 2, 2, 3, 4, 4];
let uniqueArr = [];
let obj = {};
for (let i = 0; len = arr.length; i < len; i++) {
let element = arr[i];
if (!obj[element]) {
uniqueArr.push(element);
obj[element] = true;
}
}
console.log(uniqueArr); // [1, 2, 3, 4]
这种方法在处理基本数据类型时速度比较快,但如果数组元素是对象等引用数据类型,需要根据对象的内容来判断是否重复,这种方法就需要修改,比如对对象进行序列化(如使用 JSON.stringify )后作为属性名来判断。
5.利用for循环和includes方法
- 思路是创建一个新的数组,通过 for 循环遍历原始数组。对于每个元素,检查它是否已经存在于新数组中(使用 includes 方法)。如果不存在,就将其添加到新数组中。
- 示例代码如下:
let arr = [1, 2, 2, 3, 4, 4];
let newArr = [];
for (let i = 0; i < arr.length; i++) {
if (!newArr.includes(arr[i])) {
newArr.push(arr[i]);
}
}
console.log(newArr);
这种方法的优点是比较直观,容易理解。但是 includes 方法在某些浏览器中的性能可能不是最优的,特别是对于大型数组。
6. 利用Map数据结构
与使用对象进行去重类似,不过 Map 有一些额外的优势,比如可以更好地处理对象等复杂数据类型(通过合适的键值设置)。
思路是创建一个 Map 对象,遍历数组。对于每个元素,检查 Map 中是否已经存在对应的键。如果不存在,就将元素添加到新数组中,并在 Map 中设置键值对(键为元素,值可以是任意值,比如 true )。
示例代码如下:
let arr = [1, 2, 2, 3, 4, 4];
let newArr = [];
let map = new Map();
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) {
newArr.push(arr[i]);
map.set(arr[i], true);
}
}
console.log(newArr);
Map 的 has 和 set 方法在处理数据时比较高效,而且 Map 可以更方便地处理复杂数据类型,因为它的键可以是任意数据类型,不像普通对象的键必须是字符串或符号。
7. 利用reduce方法
reduce 方法可以对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
- 思路是使用 reduce 函数,初始值是一个空数组。在每次迭代中,检查累积数组( accumulator )中是否已经包含当前元素。如果不包含,就将其添加到累积数组中。
示例代码如下:
let arr = [1, 2, 2, 3, 4, 4];
let newArr = arr.reduce((acc, cur) => {
if (!acc.includes(cur)) {
acc.push(cur);
}
return acc;
}, []);
console.log(newArr);
这种方法可以将去重操作和其他数据处理操作结合起来,在对数组进行汇总和转换的同时实现去重,不过对于简单的去重场景可能会显得稍微复杂一些。
该文章在 2024/12/20 11:25:05 编辑过