JavaScript数组去重的六种方式

 更新时间:2024年12月19日 08:28:48   作者:程序员小寒  
在平时的前端开发中,常常会遇到数组去重的场景,比如表单校验重复的数据,有重复数据不让提交,或者对后端返回的数据进行去重展示等,同时它也是一道经典的前端JavaScript基础面试题,本期一起来带大家看看去重的各种花样方法,需要的朋友可以参考下

一、最朴素的方法去重:双重for循环

一想到去重,第一个就想到了双重for循环,遍历两层比较一下就好了,不过要注意的是,用数组的splice删除重复项后,需要将第二层循环的索引减1,不然会出现数组塌陷的问题

function unique(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--; // 注意:由于删除了元素,需要将 j 减一,以避免漏掉第j项的检查
			}
		}
	}
	return arr;
}
const arr = [1,1,2,2,3,4,4,5,5,6];
console.log(unique(arr));
// 输出:[ 1, 2, 3, 4, 5, 6 ]

二、最省时间的去重:obj/Map存储 + for循环

由于对象Objectkey值唯一,所以我们可以利用这个特性进行去重。核心思路就是用对象或者Map将遍历过的项作为key存储到对象或者Map中,如果遇到已经存在的key,则说明出现了重复项,忽略此项即可。

function unique(arr) {
	const obj = {}; // 这里可以换成Map
	const newArr = [];
	for (let i = 0; i < arr.length; i++) {
		const item = arr[i];
		if (!obj[item]) {
			obj[item] = 1;
			newArr.push(item);
		}
	}
	return newArr;
}

这也是典型的空间换时间大法,可以让时间复杂度从O(n²)降为O(n),利用对象存储,达到空间换时间的效果,节约执行时间。

三、最好理解的去重:indexOf + lastIndexOf

JavaScript中提供了indexOflastIndexOf两个方法,分别拿目标项从数组的第一项最后一项开始查找,查到了会返回对应的索引值,如果某一项用indexOflastIndexOf找到的索引相同,则证明该项不存在重复项,反之就存在重复项。

这种去重方式应该是最好理解的。不过要注意,这里也使用了splice,需要注意处理防止数组塌陷的问题。

function unique(arr) {
	for (let i = 0; i < arr.length; i++) {
		if (arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i])) {
			arr.splice(i, 1);
			i--; // 注意:由于删除了元素,需要将 i 减一,以避免漏掉第i项的检查
		}
	}
	return arr;
}

四、最简单的去重:展开运算符 + Set

利用ES6的新特性,也就是展开运算符 + set应该是最简单的去重方式,写的字符数也是最少的。

function unique(arr) {
  return [...new Set(arr)];
}

五、最有趣的去重:filter + indexOf去重

利用filter + indeOf其实也可以实现去重,而且是一行代码搞定,非常有趣。

核心的思路就是,在用filter遍历时,用indexOf去查找当前遍历项的索引,如果查找到的索引与此时filter遍历的index一样,那么说明在当前项之前是没出现与当前项相同的重复项的,所以该项需要保留,反之则需要剔除,而正好filter自带过滤功能,返回true保留该项,返回false剔除该项。

function unique(arr) {
  return arr.filter((item, index) => arr.indexOf(item) === index);
}
const arr = [1,1,2,2,3,4,4,5,5,6];
console.log(unique(arr));
// 输出:[ 1, 2, 3, 4, 5, 6 ]

六、最骚的去重:JSON.stringify + Set + JSON.parse

想不到吧,利用JSON.stringify + Set + JSON.parse居然也可以实现去重,这应该是最骚的去重方式了,而且天然就支持对存放数组的对象进行去重

去重的核心思路如下:

  • 利用JSON.stringify可以将数组每一项存储的对象或者普通值都进行序列化,将原数组转为一个字符串数组;
  • 利用Set对字符串数组进行去重;
  • 利用JSON.parse对数组每一项进行反序列化。

这里注意,如果两个对象存的key和value都相同,则他们序列化的结果也相同,所以说这种方式是天然支持对对象进行去重的。

function unique(arr) {
    return [...new Set(arr.map(t => JSON.stringify(t)))].map(s => JSON.parse(s));
}
const arr = [1,1,2,2,3,4,4,5,5,6];
const arr1 = [{ a:1 }, { a:1 }, { a:2 }, { a:2 }, { a:3 }, { a:3 }, { a:4 }, { a:4 }, { a:5 }, { a:5 } ]
console.log(unique(arr));
console.log(unique(arr1));
/**
 * 打印结果:
 * [ 1, 2, 3, 4, 5, 6 ]
 * [ { a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }, { a: 5 } ]
 */

以上介绍了6种JavaScript去重方式,我平常最常用的就是第四种,也就是展开运算符 + Set去重,不知道大家在平时实际开发中更喜欢哪一种去重方式呢,或者还有没有其它的更好去重方式呢?

到此这篇关于JavaScript数组去重的六种方式的文章就介绍到这了,更多相关JavaScript数组去重内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaScript中Promise.try() 的用法小结

    JavaScript中Promise.try() 的用法小结

    本文主要介绍了JavaScript中Promise.try() 的用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-03-03
  • JS+Canvas实现贪吃蛇小游戏

    JS+Canvas实现贪吃蛇小游戏

    这篇文章介绍了JS+Canvas实现贪吃蛇小游戏,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • JavaScript仿京东放大镜特效

    JavaScript仿京东放大镜特效

    这篇文章主要为大家详细介绍了JavaScript仿京东放大镜特效,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • js计算两个日期间的天数月的实例代码

    js计算两个日期间的天数月的实例代码

    本文通过实例代码给大家介绍了基于js计算两个日期间的天数月,文中还通过一段代码给大家简单说明了js计算两个日期差的方法,感兴趣的朋友跟随小编一起看看吧
    2018-09-09
  • JavaScript事件学习小结(三)js事件对象

    JavaScript事件学习小结(三)js事件对象

    这篇文章主要介绍了JavaScript事件学习小结(三)js事件对象的相关资料,非常不错具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • 给页面渲染时间加速 干掉Dom Level 0 Event

    给页面渲染时间加速 干掉Dom Level 0 Event

    我们去掉事件绑定的逻辑,发现只渲染dom元素,不绑定事件的时间,仅仅125ms,可见事件绑定的时间消耗还是很大的 ,尤其是第一种方式,也就是Dom Level 0 Event,最为耗时
    2012-12-12
  • javascript实现的动态文字变换

    javascript实现的动态文字变换

    javascript实现的动态文字变换...
    2007-07-07
  • 通过遮罩层实现浮层DIV登录的js代码

    通过遮罩层实现浮层DIV登录的js代码

    遮罩层实现浮层DIV登录的效果,想必很多的朋友都有遇到过吧,实现起来也是很简单的,下面有个不错的实现,大家可以感受下
    2014-02-02
  • 详解如何构建Promise队列实现异步函数顺序执行

    详解如何构建Promise队列实现异步函数顺序执行

    这篇文章主要介绍了详解如何构建Promise队列实现异步函数顺序执行,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • 一个简单的js渐显(fadeIn)渐隐(fadeOut)类

    一个简单的js渐显(fadeIn)渐隐(fadeOut)类

    最近发现项目用的表单验证不好使,干脆一边参考人家的一边自己写了一个。在验证有错误返回提示信息用到渐显(fadeIn)渐隐(fadeOut)过渡(因为浏览器的效率实在太高了,一下就蹦了出来~~);
    2010-06-06

最新评论