首页 > 编程语言 >数组去重方法总结(JavaScript 记录)

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

时间:2023-07-23 23:25:45浏览次数:42  
标签:总结 abc false JavaScript NaN 数组 15 array true

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

数组去重的多种方法:

  1. 利用 ES6 Set 去重
  2. 利用 for 嵌套 for,然后 splice 去重
  3. 利用 indexOf 去重
  4. 利用 sort() 去重
  5. 利用对象的属性不能相同的特点进行去重
  6. 利用 includes 去重
  7. 利用 hasOwnProperty 去重
  8. 利用 filter 去重
  9. 利用递归去重
  10. 利用 Map 数据结构去重
  11. 利用 reduce+includes 去重
  12. [...new Set(arr)] 去重

数组去重

利用 ES6 Set 去重数组

Set 自带的特性,数据不重复

Array.from() 方法将 Set 对象转换为数组,并返回该数组作为去重后的新数组。

时间复杂度为 O(n),因为 Set 对象只需要遍历一次原数组即可完成去重操作

注:无法判断{}重复的情况

const _deleteRepeat = array => {
    return Array.from(new Set(array))
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log("去重后:=>",_deleteRepeat(arr));
//去重后:=> [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

利用 for 嵌套 for,然后 splice 去重

双层循环,外层循环元素, 内层循环时比较值。值相同时,则删去这个值。(比较相邻两个数如果重复用 splice 删除)

时间复杂度为 O(n^2),因为两层循环需要对所有元素进行比较。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️

注:无法判断NaN{} 重复的情况

const _deleteRepeat = array => {
    for (let i = 0; i < array.length; i++) {
        for (let j = i + 1; j < array.length; j++) {
            if (array[i] === array[j]) {
                array.splice(j, 1);
                j --;
            }
        }
    }
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
_deleteRepeat(arr)
console.log(arr)
// [ 1, 15, "abc", true, false, undefined, null, NaN, NaN, {}, {}]

利用 indexOf 去重

新建⼀个空的结果数组, for 循环原数组, 判断结果数组是否存在当前元素, 如果有相同的值则跳过,不相同则 push 进数组

时间复杂度为 O(n^2),因为 indexOf() 方法需要对所有元素进行比较。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️

注:无法判断NaN{} 重复的情况

const _deleteRepeat = array => {
    // 声明一个空数组,用indexOf寻找如果没有该元素则加入新数组
    let newArray = [];
    array.forEach(item => {
        if(newArray.indexOf(item) === -1) {
            newArray.push(item)
        }
    });
    return newArray;
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr));
// [ 1, 15, "abc", true, false, undefined, null, NaN, NaN, {}, {} ]

利用 sort() 去重

利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对

时间复杂度为 O(n log n),因为需要对所有元素进行排序操作。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️

注:无法判断NaN{} 重复的情况

const _deleteRepeat = array => {
    if (!Array.isArray(array)) {
        console.log("type error")
        return
    }
    array = array.sort();
    let newArray = [array[0]]
    for (let i = 1; i < array.length; i++) {
        if (array[i] !== array[i - 1]) {
            newArray.push(array[i])
        }
    }
    return newArray
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, NaN, NaN, {}, {}, "abc", false, null, true, undefined ]

利用对象的属性不能相同的特点进行去重

它会遍历输入的数组,将每个元素作为对象的属性名,如果该属性名在对象中不存在,则将其添加到对象中并将该元素添加到新数组中;如果该属性名已经存在,则不进行任何操作。最终返回去重后的新数组。

注:只能去除数组中的重复值,而不能去除数组中的重复元素(即包含多个值的元素)。如果需要去除数组中的重复元素,可以使用其他方法,比如使用 Set 数据结构或者双重循环等。⚠️

const _deleteRepeat = array => {
    if (!Array.isArray(array)) {
        console.log("type error")
        return
    }
    let newArray = [];
    let obj = {};
    array.forEach(item => {
        if(!obj[item]) {
            obj[item] = true;
            newArray.push(item);
        }
    })
    return newArray;
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {} ]

利用 includes 去重

声明一个空数组,用 includes 寻找如果没有该元素则加入新数组

时间复杂度为 O(n^2),因为需要对所有元素进行比较和查找操作。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️

注:无法判断{} 重复的情况

const _deleteRepeat = array => {
    let newArray = [];
    array.forEach(item => {
        if (!newArray.includes(item)) {
            newArray.push(item)
        }
    });
    return newArray
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

利用 hasOwnProperty 去重

利用 hasOwnProperty 检查对象是否具有指定属性

typeof {}+{} 为 object[object Object],判断有没有空对象,已经有的话 return false,没有就作为对象的属性加进去,值为 true

时间复杂度为 O(n^2),因为需要对所有元素进行比较和查找操作。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️

const _deleteRepeat = array => {
    let newArray = [];
    let obj = {};
    newArray = array.filter(item => {
        return obj.hasOwnProperty(typeof item + item) ? false : obj[typeof item +item] = true
    });
    return newArray
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {} ]

利用 filter 去重

该函数使用了 filter() 方法来筛选出数组中的唯一元素。在 filter() 方法中,传入了一个回调函数,该回调函数接受两个参数:item(当前遍历到的元素)和 index(当前元素的索引)。

在回调函数内部,我们使用indexOf() 方法查找该元素在原数组中第一次出现的位置。如果该位置与当前循环的索引相同,则说明该元素是第一次出现,需要保留;否则,说明该元素已经出现过一次,需要过滤掉。

注:无法判断{} 重复的情况(无法判断 NaN)

const _deleteRepeat = array => {
    return array.filter((item, index) => {
        return array.indexOf(item) === index
    })
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, {}, {} ]

利用递归去重

时间复杂度是 O(n^2),因为在每次递归调用时都需要遍历整个数组来查找重复元素。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️

注:无法判断{}NaN重复的情况

const _deleteRepeat = array=>  {
    let len = array.length;
    // 排序后更加方便去重
    array = array.sort();
    const loop = index => {
        if (index >= 1) {
            if (array[index] === array[index - 1]) {
                array.splice(index, 1);
            }
            // 递归loop,然后数组去重
            loop(index - 1);
        }
    }
    loop(len - 1);
    return array;
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, NaN, NaN, {}, {}, "abc", false, null, true, undefined ]

利用Map数据结构去重

创建⼀个空 Map 数据结构, 遍历需要去重的数组, 把数组的每⼀个元素作为 key 存到 Map 中。由于 Map 中不会出现相同的 key 值,所以最终得到的就是去重后的结果

时间复杂度为 O(n),因为只需要对所有元素进行一次遍历和查找操作。因此,这种方法在处理大型数组时具有较好的性能。

注:无法判断{} 重复的情况

const _deleteRepeat = array => {
    let newArray = [];
    let map = new Map();
    array.forEach(item => {
        if (!map.has(item)) {
            map.set(item, true);
            newArray.push(item);
        }
    });
    return newArray
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

利用 reduce+includes 去重

reduce() 方法遍历原数组

对于每个元素 item,我们使用 includes() 方法来检查该元素是否已经存在于累加器数组 accumulator 中。如果不存在,则使用 push() 方法将该元素添加到累加器数组中。最后,我们返回累加器数组作为去重后的新数组。

时间复杂度为 O(n^2),因为需要对所有元素进行比较和查找操作。因此,这种方法在处理大型数组时可能会导致性能问题。⚠️

注:无法判断{} 重复的情况

const _deleteRepeat = array => {
    return array.reduce((accumulator, item) => {
        if (!accumulator.includes(item)) {
            accumulator.push(item);
        }
        return accumulator;
    }, []);
};
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

[...new Set(arr)]

利用扩展运算符 ...Set 对象去重数组

时间复杂度为 O(n),Set 对象只需要遍历一次原数组即可完成去重操作

注:无法判断{}重复的情况

const _deleteRepeat = array => {
    return [...new Set(array)];
}
let  arr = [1, 1, 15, 15, 'abc', 'abc',
          true, true, false, false, undefined, undefined,
          null, null, NaN, NaN, {}, {}];
console.log(_deleteRepeat(arr))
// [ 1, 15, "abc", true, false, undefined, null, NaN, {}, {} ]

标签:总结,abc,false,JavaScript,NaN,数组,15,array,true
From: https://www.cnblogs.com/ikunblog/p/17576150.html

相关文章

  • Nacos2作为Dubbo3的配置中心踩坑总结
    本文阐述问题所使用的组件版本分别是,Dubbo:3.2.4,Nacos服务端:2.2.3,Nacos客户端:2.2.4。在Dubbo3的官方文档中,关于如何使用Nacos作为配置中心的详细介绍参考:Nacos。但非常沮丧的是我参照文档的描述,并没有成功将Nacos2配置成为Dubbo3项目的配置中心。期间也看到有人在github上提出相......
  • 7月23日总结
    7月23日总结遗传算法相关https://zhuanlan.zhihu.com/p/378906456国赛2021c、d题复变函数论https://blog.csdn.net/qq_39942341/article/details/119870648......
  • 假期第五周每周总结
       本周,学习了大数据相关的知识,首先先是在中国大学mood上看了会课程,了解了基本的概念,然后进行配置,然后配置过程太简略,一直配置失败,就在b站上找相关的课程,在黑马程序员那里看的有点人少,毕竟出来bug也不知怎么解决,然后就找到了b站的尚硅谷的大数据进行学习,学习了几天,还行,至少......
  • linux 中 awk数组统计每列、行数据之和及平均值
     001、列[root@PC1test02]#lsa.txt[root@PC1test02]#cata.txt##测试数据362825841382##统计每列数据之和[root@PC1test02]#awk'{for(i=1;i<=NF;......
  • 背包问题总结
    背包问题总结目录01背包问题完全背包问题多重背包问题朴素版本优化版本分组背包问题01背包问题AcWing2.01背包问题AcWing打卡另外的参考//01背包问题——每件物品最多只用一次/*//二维动态规划分析:f[i][j]表示只看前i个物品,总体积是j的情况下,总价值最大是......
  • 2023-07-23:给你 n 个任务和 m 个工人 每个任务需要一定的力量值才能完成 需要的力量值
    2023-07-23:给你n个任务和m个工人每个任务需要一定的力量值才能完成需要的力量值保存在下标从0开始的整数数组tasks中第i个任务需要tasks[i]的力量才能完成每个工人的力量值保存在下标从0开始的整数数组workers中第j个工人的力量值为workers[j]每个工人只......
  • 线程安全的数组java
    实现线程安全的数组(Java)概述在Java开发中,线程安全是一个非常重要的概念。当多个线程同时访问和修改共享资源时,如果不采取相应的措施,就可能导致数据不一致或者出现其他的并发问题。本文将介绍如何实现一个线程安全的数组,以保证在多线程环境下对数组的访问和修改是安全的。实现步......
  • JavaScript jQuery 比对示例,ajax示例
    js教程:https://www.w3school.com.cn/js/index.aspjQuery教程:https://www.w3school.com.cn/jquery/index.asp以下是部分代码示例<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>javascript</t......
  • 20230723练习总结
    CF923DPickingStrings当变化规则不好分析的时候可以考虑自己随便模拟一下变化过程,总结浓缩出一些等价且更简单的变化规则。尝试推出几个比较简单的变化关系:\(\texttt{B}\rightarrow\texttt{AC}\rightarrow\texttt{AAB}\rightarrow\texttt{AAAC}\rightarrow\texttt{C}\right......
  • 笔记-C-typdef定义数组
    typdef定义数组后的初始化|计算机内部只知晓地址,类型为上层的高级语义#include<stdio.h>typedefintARR_INT_2[2];voidtest(ARR_INT_2*t){int*t1;int*t2;t1=&(((int*)t)[0]);t2=&(((int*)t)[1]);printf("t1addr-%p\n",t1);......