0

0

javascript如何实现数组去重_有哪些高效的方案【教程】

紅蓮之龍

紅蓮之龍

发布时间:2026-01-28 15:50:03

|

742人浏览过

|

来源于php中文网

原创

JavaScript数组去重无唯一最优解,需据数据特征选方案:基础类型且需保序用Set+扩展运算符;对象数组须自定义比较逻辑;超大数组优先用Map/Object哈希表降为O(n)。

javascript如何实现数组去重_有哪些高效的方案【教程】

JavaScript 数组去重没有唯一“最优解”,方案选择取决于你的数据特征和约束条件:是否需保持顺序、是否含对象、是否考虑性能、是否兼容旧环境。

Set + 扩展运算符是最简且现代的写法

适用于基础类型(stringnumberbooleannullundefined)且需保持原始顺序的场景。它底层基于唯一值语义,代码简洁、可读性强、V8 引擎优化充分。

常见错误是误以为能处理对象数组:[{a:1}, {a:1}][...new Set(arr)] 后仍是两个元素,因为对象引用不同。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 确认数组元素全是基础类型再用此法
  • IE 不支持 Set 或扩展运算符,需转译或降级
  • 小到中等规模数组(
const arr = [1, 2, 2, 3, 'a', 'a'];
const unique = [...new Set(arr)]; // [1, 2, 3, 'a']

filter + indexOf 兼容性好但注意性能陷阱

适合需要支持 IE9+ 且数据量不大的项目。原理是只保留首次出现的元素索引位置一致的项。

容易踩的坑:

燕雀Logo
燕雀Logo

为用户提供LOGO免费设计在线生成服务

下载
  • indexOfNaN 返回 -1,导致所有 NaN 都被保留(实际应视为相同值)
  • 时间复杂度 O(n²),数组超 1 万项时明显变慢
  • 无法区分 0false(两者 indexOf 查找结果可能互相干扰,取决于数组内容)
const arr = [1, 2, 2, 3];
const unique = arr.filter((item, index) => arr.indexOf(item) === index);

处理对象数组必须自定义比较逻辑

不能依赖 SetindexOf,因为它们比的是引用而非结构。常见做法是用 reduce + some 或构建临时键(如 JSON 序列化)。

关键权衡点:

  • JSON.stringify 简单但不可靠:属性顺序敏感、忽略函数/undefined/symbol、循环引用直接报错
  • some 比较安全但性能差,O(n²),适合几百项以内
  • 真要高性能且健壮,得用 Lodash 的 uniqBy 或手写基于 Map 的哈希键生成(如取特定字段拼接)
const arr = [{id: 1}, {id: 1}, {id: 2}];
const unique = arr.filter((item, index, self) =>
  index === self.findIndex(obj => obj.id === item.id)
);

超大数组(>10 万)优先用 MapObject 做哈希表

当明确知道元素类型且可构造唯一键(如数字 ID、字符串 name),用哈希表可将时间复杂度降到 O(n),避免 Set 在某些引擎下对非基础类型的隐式转换开销。

注意点:

  • Object 键会强制转为字符串,{'0':1, '1':2}{0:1, 1:2} 是一样的,对纯数字 ID 安全;但若含 truenull 等,String(true) === 'true',没问题;String(undefined)'undefined',也无歧义
  • Map 更通用,支持任意类型作键,但内存占用略高
  • 不要在键里拼接未转义的用户输入,防止键冲突(比如 name + '_' + id 中 name 含下划线)
const arr = [1, 2, 2, 3];
const seen = new Map();
const unique = arr.filter(item => {
  if (seen.has(item)) return false;
  seen.set(item, true);
  return true;
});

真正难的不是写出一个去重函数,而是判断当前数组里到底存的是什么——是简单数字?带空值的混合类型?还是嵌套很深的对象?选错方案轻则结果不对,重则页面卡死。别抄完代码就跑,先 console.log(typeof arr[0]) 看一眼。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

443

2023.08.02

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

350

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

29

2025.11.30

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

236

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

438

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1501

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

232

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

87

2025.10.17

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号