JS数组去重有几种类型,分别怎么实现
Admin 2022-06-18 群英技术资讯 733 次浏览
// 测试用例 const a = {}; const b = { c: 1 }; const array = [ 1, 1, "1", "1", {}, {}, { c: 1 }, { c: 1}, a, a, b, b, [], [], [1], [1], undefined, undefined, null, null, NaN, NaN, ];
此类型通过数组元素之间进行比较来去重
使用双层for循环逐一比较数组元素,用splice
方法去除重复的元素
// 双层for循环 function uniq1(arr) { 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-- } } } return arr } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN,NaN]
通过对比去重前后结果,重复的NaN
没有去掉,因为NaN === NaN
为false
使用sort()
方法对数组元素进行排序,然后比较相邻元素,用splice
方法去除重复的元素。
function uni2(arr) { arr.sort(); for (let i = 0; i < arr.length - 1; i++) { arr[i] === arr[i + 1] && arr.splice(i + 1, 1) && i--; } return arr; }
也可以创建新数组,将不重复的元素放入新数组中
function uniq3(arr) { arr = arr.sort() const newArr = [arr[0]] for (let i = 1; i < arr.length; i++) { if (arr[i] !== arr[i - 1]) { newArr.push(arr[i]) } } return newArr } // 去重结果 // [[],[],1,'1',[1],[1],NaN,NaN,{},{},{c:1},{c:1},{},{c:1},null,undefined]
重复的NaN
没有去掉,因为NaN === NaN为false
默认排序顺序是将元素转换为字符串,对象转换为字符串都是
sort[object Object]
,所以sort
方法不能对数组中的对象进行排序,也就有可能无法去除重复的对象,除非重复的对象本就相邻
此类型通过查找元素第一次出现的位置来去重
通过indexOf
查找当前元素第一次出现的位置是否为当前位置,若是,则放入新数组
function uniq4(arr) { let res = [] for (let i = 0; i < arr.length; i++) { if (arr.indexOf(arr[i]) === i) { res.push(arr[i]) } } return res } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null]
同样,因为NaN === NaN
为false
,所以用indexOf
查找NaN
结果总是-1,从而在新数组中不会有NaN
通过findIndex
查找当前元素第一次出现的位置是否为当前位置,若是,则放入新数组
function uniq5(arr) { let res = [] for (let i = 0; i < arr.length; i++) { if (arr.findIndex(item => item === arr[i]) === i) { res.push(arr[i]) } } return res } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null]
同样,因为NaN === NaN
为false
,所以用findIndex
查找NaN
结果总是-1,从而在新数组中不会有NaN
此类型通过判断在新数组中是否存在当前元素来去重
includes
方法用来判断一个数组是否包含一个指定的值
function uniq6(arr) { let res = [] for (let i = 0; i < arr.length; i++) { if (!res.includes(arr[i])) { res.push(arr[i]) } } return res } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN]
includes
使用零值相等算法来确定是否找到给定的元素,所以可以判断NaN是否在新数组中存在
some
方法用来测试数组中是否至少有1个元素通过了被提供的函数测试
function uniq7(arr) { let res = [] for (let i = 0; i < arr.length; i++) { if (!res.some(item => item === arr[i])) { res.push(arr[i]) } } return res } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN,NaN]
同样,这里仍旧使用了===
来比较元素,因为NaN === NaN
为false
,所以新数组中会有多个NaN
此类型通过ES6提供的数据结构Map
、Set
本身不可重复特性来去重
ES6
提供的Map结构可以用各种类型的值(包括对象)当作键,且键是唯一的
function uniq8(arr) { const map = new Map() for (let i = 0; i < arr.length; i++) { !map.has(arr[i]) && map.set(arr[i], true) } return [...map.keys()] } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN]
map.has
方法对NaN
也有效
Set
结构的成员的值都是唯一的,没有重复的值。
function uniq9(arr) { return [...new Set(arr)] } // 去重结果 // [1,'1',{},{},{c:1},{c:1},{},{c:1},[],[],[1],[1],undefined,null,NaN]
上面所说的方法可以使用不同的Api
进行改动,比如使用splice
方法去除数组元素的地方,我们可以通过filter
方法来过滤数组得到新数组;
再比如includes
的方法中不用for
循环遍历数组,通过reduce
方法来代替等等。
总之,方法有很多,但是万变不离其宗
有些去重方法对NaN
无效,因为NaN === NaN
为false
,如果有需求,可以使用Object.is(NaN, NaN)
为true
来进行修改
实际应用中,最常用的方法就是使用Set,也可以使用第三方库lodash
来处理
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
vue渲染不上数据的问题如何解决?这里提到的vue渲染不上数据的问题是能获取到数据,但是数据却渲染不到页面上。那么什么方法可以解决这个问题呢?下面我们一起来探讨一下。
目录懒加载组件问题与解决方案加载中组件错误处理组件preload 和 prefetch总结前端开发中,随着业务和页面增加,以组件为基本单位的结构下,组件数量会增长极快,为了优化我们会很显然地想要进行一些工作:代码分块懒加载非必要资源文件非必要资源,指的首次渲染出某页面所不必要的资源,如因为用户操作才出现的图片、弹窗等。
在JavaScript中,round()方法的意思是将数字进行四舍五入计算,该方法可以把一个数字舍入为最接近的整数,返回的结果就是四舍五入后的结果,语法为“Math.round(数字)”。
基于element-plus的二次封装数据双向绑定在实际开发中,经常需要基于element-plus封装一些自己的定制化组件,方便快速构建我们当前的业务。在vue2.0中父子组件数据的双向绑定通
jquery禁止div的方法:1、使用JQuery的off()方法禁用div;2、使用JQuery结合CSS的“pointer-events: none;”实现禁用div即可。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008