翼度科技»论坛 编程开发 JavaScript 查看内容

数组去重方法总结(JavaScript 记录)

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
在进行项目开发的时候,有时候需要把一些前端的数组进行去重处理,得到一个去重后的数据,然后再进行相关的操作,这也是在前端面试中经常出现的问题
数组去重的多种方法:

  • 利用 ES6 Set 去重
  • 利用 for 嵌套 for,然后 splice 去重
  • 利用 indexOf 去重
  • 利用 sort() 去重
  • 利用对象的属性不能相同的特点进行去重
  • 利用 includes 去重
  • 利用 hasOwnProperty 去重
  • 利用 filter 去重
  • 利用递归去重
  • 利用 Map 数据结构去重
  • 利用 reduce+includes 去重
  • [...new Set(arr)] 去重
数组去重

利用 ES6 Set 去重数组

Set 自带的特性,数据不重复
Array.from() 方法将 Set 对象转换为数组,并返回该数组作为去重后的新数组。
时间复杂度为 O(n),因为 Set 对象只需要遍历一次原数组即可完成去重操作
注:无法判断{}重复的情况
  1. const _deleteRepeat = array => {
  2.     return Array.from(new Set(array))
  3. }
  4. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  5.           true, true, false, false, undefined, undefined,
  6.           null, null, NaN, NaN, {}, {}];
  7. console.log("去重后:=>",_deleteRepeat(arr));
  8. //去重后:=> [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]
复制代码
利用 for 嵌套 for,然后 splice 去重

双层循环,外层循环元素, 内层循环时比较值。值相同时,则删去这个值。(比较相邻两个数如果重复用 splice 删除)
时间复杂度为 O(n^2),因为两层循环需要对所有元素进行比较。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️
注:无法判断NaN 及 {} 重复的情况
  1. const _deleteRepeat = array => {
  2.     for (let i = 0; i < array.length; i++) {
  3.         for (let j = i + 1; j < array.length; j++) {
  4.             if (array[i] === array[j]) {
  5.                 array.splice(j, 1);
  6.                 j --;
  7.             }
  8.         }
  9.     }
  10. }
  11. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  12.           true, true, false, false, undefined, undefined,
  13.           null, null, NaN, NaN, {}, {}];
  14. _deleteRepeat(arr)
  15. console.log(arr)
  16. // [ 1, 15, "abc", true, false, undefined, null, NaN, NaN, {}, {}]
复制代码
利用 indexOf 去重

新建⼀个空的结果数组, for 循环原数组, 判断结果数组是否存在当前元素, 如果有相同的值则跳过,不相同则 push 进数组
时间复杂度为 O(n^2),因为 indexOf() 方法需要对所有元素进行比较。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️
注:无法判断NaN 及 {} 重复的情况
  1. const _deleteRepeat = array => {
  2.     // 声明一个空数组,用indexOf寻找如果没有该元素则加入新数组
  3.     let newArray = [];
  4.     array.forEach(item => {
  5.         if(newArray.indexOf(item) === -1) {
  6.             newArray.push(item)
  7.         }
  8.     });
  9.     return newArray;
  10. }
  11. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  12.           true, true, false, false, undefined, undefined,
  13.           null, null, NaN, NaN, {}, {}];
  14. console.log(_deleteRepeat(arr));
  15. // [ 1, 15, "abc", true, false, undefined, null, NaN, NaN, {}, {} ]
复制代码
利用 sort() 去重

利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对
时间复杂度为 O(n log n),因为需要对所有元素进行排序操作。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️
注:无法判断NaN 及 {} 重复的情况
  1. const _deleteRepeat = array => {
  2.     if (!Array.isArray(array)) {
  3.         console.log("type error")
  4.         return
  5.     }
  6.     array = array.sort();
  7.     let newArray = [array[0]]
  8.     for (let i = 1; i < array.length; i++) {
  9.         if (array[i] !== array[i - 1]) {
  10.             newArray.push(array[i])
  11.         }
  12.     }
  13.     return newArray
  14. }
  15. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  16.           true, true, false, false, undefined, undefined,
  17.           null, null, NaN, NaN, {}, {}];
  18. console.log(_deleteRepeat(arr))
  19. // [ 1, 15, NaN, NaN, {}, {}, "abc", false, null, true, undefined ]
复制代码
利用对象的属性不能相同的特点进行去重

它会遍历输入的数组,将每个元素作为对象的属性名,如果该属性名在对象中不存在,则将其添加到对象中并将该元素添加到新数组中;如果该属性名已经存在,则不进行任何操作。最终返回去重后的新数组。
注:只能去除数组中的重复值,而不能去除数组中的重复元素(即包含多个值的元素)。如果需要去除数组中的重复元素,可以使用其他方法,比如使用 Set 数据结构或者双重循环等。⚠️
  1. const _deleteRepeat = array => {
  2.     if (!Array.isArray(array)) {
  3.         console.log("type error")
  4.         return
  5.     }
  6.     let newArray = [];
  7.     let obj = {};
  8.     array.forEach(item => {
  9.         if(!obj[item]) {
  10.             obj[item] = true;
  11.             newArray.push(item);
  12.         }
  13.     })
  14.     return newArray;
  15. }
  16. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  17.           true, true, false, false, undefined, undefined,
  18.           null, null, NaN, NaN, {}, {}];
  19. console.log(_deleteRepeat(arr))
  20. // [ 1, 15, "abc", true, false, undefined, null, NaN, {} ]
复制代码
利用 includes 去重

声明一个空数组,用 includes 寻找如果没有该元素则加入新数组
时间复杂度为 O(n^2),因为需要对所有元素进行比较和查找操作。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️
注:无法判断{} 重复的情况
  1. const _deleteRepeat = array => {
  2.     let newArray = [];
  3.     array.forEach(item => {
  4.         if (!newArray.includes(item)) {
  5.             newArray.push(item)
  6.         }
  7.     });
  8.     return newArray
  9. }
  10. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  11.           true, true, false, false, undefined, undefined,
  12.           null, null, NaN, NaN, {}, {}];
  13. console.log(_deleteRepeat(arr))
  14. // [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]
复制代码
利用 hasOwnProperty 去重

利用 hasOwnProperty 检查对象是否具有指定属性
typeof {}+{} 为 object[object Object],判断有没有空对象,已经有的话 return false,没有就作为对象的属性加进去,值为 true
时间复杂度为 O(n^2),因为需要对所有元素进行比较和查找操作。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️
  1. const _deleteRepeat = array => {
  2.     let newArray = [];
  3.     let obj = {};
  4.     newArray = array.filter(item => {
  5.         return obj.hasOwnProperty(typeof item + item) ? false : obj[typeof item +item] = true
  6.     });
  7.     return newArray
  8. }
  9. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  10.           true, true, false, false, undefined, undefined,
  11.           null, null, NaN, NaN, {}, {}];
  12. console.log(_deleteRepeat(arr))
  13. // [ 1, 15, "abc", true, false, undefined, null, NaN, {} ]
复制代码
利用 filter 去重

该函数使用了 filter() 方法来筛选出数组中的唯一元素。在 filter() 方法中,传入了一个回调函数,该回调函数接受两个参数:item(当前遍历到的元素)和 index(当前元素的索引)。
在回调函数内部,我们使用indexOf() 方法查找该元素在原数组中第一次出现的位置。如果该位置与当前循环的索引相同,则说明该元素是第一次出现,需要保留;否则,说明该元素已经出现过一次,需要过滤掉。
注:无法判断{} 重复的情况(无法判断 NaN)
  1. const _deleteRepeat = array => {
  2.     return array.filter((item, index) => {
  3.         return array.indexOf(item) === index
  4.     })
  5. }
  6. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  7.           true, true, false, false, undefined, undefined,
  8.           null, null, NaN, NaN, {}, {}];
  9. console.log(_deleteRepeat(arr))
  10. // [ 1, 15, "abc", true, false, undefined, null, {}, {} ]
复制代码
利用递归去重

时间复杂度是 O(n^2),因为在每次递归调用时都需要遍历整个数组来查找重复元素。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️
注:无法判断{} 、NaN重复的情况
  1. const _deleteRepeat = array=>  {
  2.     let len = array.length;
  3.     // 排序后更加方便去重
  4.     array = array.sort();
  5.     const loop = index => {
  6.         if (index >= 1) {
  7.             if (array[index] === array[index - 1]) {
  8.                 array.splice(index, 1);
  9.             }
  10.             // 递归loop,然后数组去重
  11.             loop(index - 1);
  12.         }
  13.     }
  14.     loop(len - 1);
  15.     return array;
  16. }
  17. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  18.           true, true, false, false, undefined, undefined,
  19.           null, null, NaN, NaN, {}, {}];
  20. console.log(_deleteRepeat(arr))
  21. // [ 1, 15, NaN, NaN, {}, {}, "abc", false, null, true, undefined ]
复制代码
利用Map数据结构去重

创建⼀个空 Map 数据结构, 遍历需要去重的数组, 把数组的每⼀个元素作为 key 存到 Map 中。由于 Map 中不会出现相同的 key 值,所以最终得到的就是去重后的结果
时间复杂度为 O(n),因为只需要对所有元素进行一次遍历和查找操作。因此,这种方法在处理大型数组时具有较好的性能。
注:无法判断{} 重复的情况
  1. const _deleteRepeat = array => {
  2.     let newArray = [];
  3.     let map = new Map();
  4.     array.forEach(item => {
  5.         if (!map.has(item)) {
  6.             map.set(item, true);
  7.             newArray.push(item);
  8.         }
  9.     });
  10.     return newArray
  11. }
  12. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  13.           true, true, false, false, undefined, undefined,
  14.           null, null, NaN, NaN, {}, {}];
  15. console.log(_deleteRepeat(arr))
  16. // [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]
复制代码
利用 reduce+includes 去重

reduce() 方法遍历原数组
对于每个元素 item,我们使用 includes() 方法来检查该元素是否已经存在于累加器数组 accumulator 中。如果不存在,则使用 push() 方法将该元素添加到累加器数组中。最后,我们返回累加器数组作为去重后的新数组。
时间复杂度为 O(n^2),因为需要对所有元素进行比较和查找操作。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️
注:无法判断{} 重复的情况
  1. const _deleteRepeat = array => {
  2.     return array.reduce((accumulator, item) => {
  3.         if (!accumulator.includes(item)) {
  4.             accumulator.push(item);
  5.         }
  6.         return accumulator;
  7.     }, []);
  8. };
  9. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  10.           true, true, false, false, undefined, undefined,
  11.           null, null, NaN, NaN, {}, {}];
  12. console.log(_deleteRepeat(arr))
  13. // [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]
复制代码
[...new Set(arr)]

利用扩展运算符 ... 和 Set 对象去重数组
时间复杂度为 O(n),Set 对象只需要遍历一次原数组即可完成去重操作
注:无法判断{}重复的情况
  1. const _deleteRepeat = array => {
  2.     return [...new Set(array)];
  3. }
  4. let  arr = [1, 1, 15, 15, 'abc', 'abc',
  5.           true, true, false, false, undefined, undefined,
  6.           null, null, NaN, NaN, {}, {}];
  7. console.log(_deleteRepeat(arr))
  8. // [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]
复制代码
来源:https://www.cnblogs.com/ikunblog/p/17576150.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具