使用 Set 方法实现数组去重
使用Set
方法实现数组去重非常简单,只需要将去重的数组转换为Set
对象,再将Set
对象转换回数组即可。
const arr = [1, 2, 3, 3, 4, 5, 5];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]
在上述代码中,首先创建了一个包含重复元素的数组arr
,然后通过使用Set
构造函数将其转换为Set
对象,再使用扩展运算符...
将Set
对象转换回数组。由于Set
对象指挥存储不重复的值,因此转换后的数组uniqueArr
中就只包含了原数组中的不重复元素。
在这里需要注意的是,再使用Set
的时候需要将其传入一个可迭代对象。因此我们也可以直接使用Set
构造函数来实现数组去重。
const arr = [1, 2, 3, 3, 4, 5, 5];
const set = new Set(arr);
const uniqueArr = Array.from(set);
console.log(uniqueArr); // 输出 [1, 2, 3, 4, 5]
再上述代码中,使用了Arrat.from()
方法将Set
对象转换为数组。
使用 filter 方法实现数组去重
当我们需要使用filter
方法对数组进行去重操作时,可以使用filter
方法配合indexOf
方法来实现。首先需要定义一个空数组,用于存放去重后的元素,然后使用filter
方法遍历原始数组,对于每个元素来说,如果它们不存在于新数组,那么就把它添加到新数组,最后返回新数组即可得到去重后的数组。
const arr = [1, 2, 3, 2, 4, 3];
const result = arr.filter(function(item, index, array) {
// 如果当前元素是第一次出现,则返回 true,否则返回 false
return array.indexOf(item) === index;
});
console.log(result); // [1, 2, 3, 4]
在上述代码中,filter
方法接受一个回调函数作为参数。该回调函数将会被传递三个参数,分别是当前元素item
、元素索引index
和原始数组array
。
在回调函数中,通过indexOf
方法获取当前元素在数组中第一次出现的位置,如果该位置等于当前索引,说明该元素是第一次出现,即为不重复元素,返回true
;反之,如果该位置小于当前索引,就说明该元素已经在前面的迭代中出现过,即为重复元素,返回false
。当filter
方法返回true
时,该元素将被添加到result
数组中,这样便可以得到一个去重后的新数组。
使用 indexOf 方法实现数组去重
当数组中的元素为基本数据类型时,indexOf
方法可以用来判断元素中是否已经存在于结果数组中。这是因为indexOf
方法返回要查找元素在数组中第一次出现的索引值。如果该元素在数组中并不存在,则返回-1
。因此,在遍历原始数组时,我们可以使用indexOf
方法来判断当前元素是否存在于结果数组中。如果不存在,则将其添加到结果数组中。
function unique(array) {
let result = [];
array.forEach(function(item) {
if (result.indexOf(item) === -1) {
result.push(item);
}
});
return result;
}
// 示例
let arr = [1, 2, 3, 2, 1];
console.log(unique(arr)); // [1, 2, 3]
上述代码中,我们首先创建了一个空数组result
来存储去重后的结果。紧接着使用forEach
方法来便利原始数组arry
,如果在result
中没有找到当前元素item
,则将其添加到result
中。最后返回result
数组即可。
但是需要注意的是,当数组中包含对象等复杂数据类型时,由于对象在内存中的引用地址不同,即使两个对象的属性完全相同,它们也不会被视为相同元素。因此,上述方法无法对这种情况进行去重。
使用 includes 方法实现数组去重
includes
方法与indexOf
方法的实现过程基本相同,这是因为includes
与indexOf
方法功能近似。因为includes
是 JavaScript 中的一个数组方法,它主要用于检查数组中是否包含指定的值,并返回布尔值。如果该值存在于数组中,则返回true
;否则,返回false
。
let arr = [1, 2, 2, 3, 4, 4, 5];
let newArr = [];
for (let i = 0; i < arr.length; i++) {
if (!newArr.includes(arr[i])) { // 检查该元素是否已经存在于新数组中
newArr.push(arr[i]); // 如果不存在则将该元素添加到新数组中
}
}
console.log(newArr); // 输出 [1, 2, 3, 4, 5]
在上述代码中,使用includes
方法检查当前元素是否存在与新数组中,如果不存在则将其添加到新数组中,由于includes
方法返回的是一个布尔值,因此需要使用逻辑非运算符将其转换为if
语句需要的true/false
值相反的形式。在这段代码的if
判断语句之中,逻辑非运算符!
主要是用来判断当前元素是否存在于新数组newArr
之中,如果不存在则执行if
代码块中的操作,将该元素添加到newArr
中。具体来说,当newArr.includes(arr[i])
的结果为false
时,表明了newArr
数组中还没有包含当前元素arr[i]
,所以需要将其添加到newArr
中,因此,需要逻辑非运算符!
将上述条件转换为布尔类型的true
。如果不使用逻辑非运算符!
,而是直接写成if(newArr.includes(arr[i]))
,则表示只有在newArr
中已经包含当前元素时才会执行if
代码块中的逻辑,即将重复的元素再次添加到newArr
中,从而造成结果数组中出现重复元素的问题。
使用 splice 方法实现数组去重
使用splice
方法实现数组去重并不是一种常用的方法,因为splice
方法主要用于在数组中添加或删除元素,对于去重这个需求来说并不是最优解决方案。具体的实现方式是遍历数组中的每一个元素,然后再从该元素之后的位置开始依次比较,如果找到相同元素,使用splice
方法将其删除。
let arr = [1, 2, 3, 4, 1, 2];
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]
在上述代码中,首先使用for
循环遍历数组中的每一个元素,然后再从该元素之后的位置开始一次比较,如果找到相同元素,则使用splice
方法将其从数组中删除。但是需要注意的是,在使用splice
方法删除元素时,需要将当前循环索引的值
−
1
-1
−1,否则将会漏掉一些重复的元素。
虽然此种方法可以实现数组去重,但是由于涉及到多次修改数组,所以效率并不是很高,还可能会影响程序性能。因此,在实际开发过程中,并不建议使用。
使用 sort 方法实现数组去重
使用sort
方法实现数组去重并不是一种常用的方法。具体的实现方式是通过排序将相同元素紧密排列,然后再遍历数组,将相邻重复的元素进行剔除。
function unique(arr) {
arr.sort();
let len = arr.length;
let result = [arr[0]];
for (let i = 0; i < len; i++) {
if (arr[i] !== arr[i-1]) {
result.push(arr[i]);
}
}
return result;
}
此算法的时间复杂度为 O(nlogn),因为涉及到了对数组进行排序,所以在实际应用中较为少见。虽然其优秀程度不如其它算法,但了解其实现思路有助于深入理解 JavaScript 数组去重原理。
使用对象实现数组去重
当我们使用对象对数组进行去重时,实际上是利用了对象属性名的唯一性来达到去重的目的。首先我们创建一个空对象obj
。然后,使用forEach()
方法遍历数组中的每个元素,将元素作为对象的属性名存入对象中,同时给每个属性赋值为true
。由于对象的属性名是唯一的,因此如果数组中有重复的元素,只会将第一个遇到的元素作为属性名存储到对象中,后续遇到的相同元素就不会再被存储了。最后,我们使用Object.keys()
方法获取对象中的所有属性名,即为去重后的数组。
const arr = [1, 2, 2, 3, 3, 4, 5, 5];
const obj = {};
arr.forEach((item) => {
obj[item] = true;
});
console.log(obj); // 输出 { '1': true, '2': true, '3': true, '4': true, '5': true }
const uniqueArr = Object.keys(obj);
console.log(uniqueArr); // 输出 [ '1', '2', '3', '4', '5' ]
在上述代码中,我们遍历数组中的每个元素,并将元素作为对象的属性名存入对象之中。由于对象的属性名是唯一的,因此就可以实现数组去重的效果。最后,我们使用Object.keys()
方法获取了对象中的所有属性名,即为去重后的数组。
使用 reduce 方法实现数组去重
在 JavaScript 中可以使用reduce
方法和includes
方法来实现数组去重。
const arr = [1, 2, 3, 2, 4, 5, 1];
const uniqueArr = arr.reduce((prev, cur) => {
if (!prev.includes(cur)) {
prev.push(cur);
}
return prev;
}, []);
console.log(uniqueArr); // [1, 2, 3, 4, 5]
当我们使用reduce
方法时,需要传入两个参数:一个是回调函数,另一个是初始值。回调函数有两个参数,第一个参数是累加器(也就是上一次回调函数的返回值),第二个参数是当前数组元素。在上述代码示例中,我们将初始值设为空数组[]
。在每次回调函数执行时,我们首先使用includes
方法判断当前元素是否已经存在于累加器prev
中,如果不存在,则将该元素推入prev
数组之中。最终,reduce
方法则会返回去重后的数组uniqueArr
。
简单来说reduce
方法遍历原数组,并将每个元素与prev
数组进行比较,如果prev
数组中不包含该元素,则将该元素添加到prev
数组中。最终返回去重后的数组uniqueArr
。
但是需要注意的是,这种方法虽然能够去除重复项,但是由于每个元素都需要遍历一边数组进行比较,所以效率较低。如果数据量较大,推荐使用其它更为搞笑的去重方法,譬如使用Set
或者对象属性来判断是否出现过。