在JavaScript中,如何给字符串数组中的元素去重

在 JavaScript 中,给字符串数组(或其他类型数组)去重有多种方法,下面列举几种常用的方式,并说明各自的特点。


1. 利用 Set(最简洁、推荐)

Set 是 ES6 新增的数据结构,它类似于数组,但成员的值都是唯一的。将数组传入 Set 构造函数,再通过扩展运算符或 Array.from() 转回数组即可。

javascript 复制代码
const arr = ['apple', 'banana', 'apple', 'orange', 'banana'];
const unique = [...new Set(arr)];
console.log(unique); // ['apple', 'banana', 'orange']

优点 :代码简洁,效率高(时间复杂度 O(n))。
缺点 :无法保留原数组中的元素顺序吗?------会保留第一次出现的顺序,Set 遍历顺序就是插入顺序,因此顺序是保持的。所以一般没有缺点。但注意 :Set 去重使用"SameValueZero"比较,认为 NaN 与自身相等,而 === 不认为相等;在字符串数组中基本无影响。


2. 利用 filter + indexOf

通过数组自身的 filter 方法,配合 indexOf 检测当前元素第一次出现的位置是否等于当前索引。

javascript 复制代码
const arr = ['apple', 'banana', 'apple', 'orange', 'banana'];
const unique = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(unique); // ['apple', 'banana', 'orange']

优点 :兼容性非常好(ES5 即可),语义清晰。
缺点indexOf 会从头遍历数组,整体时间复杂度 O(n²),在大型数组上性能较差。同时 indexOf 无法正确查找 NaN,但字符串数组通常无此问题。


3. 利用 reduce 累加器

通过 reduce 构建新数组,判断当前元素是否已存在于累加器中。

javascript 复制代码
const arr = ['apple', 'banana', 'apple', 'orange', 'banana'];
const unique = arr.reduce((acc, cur) => {
  if (!acc.includes(cur)) {
    acc.push(cur);
  }
  return acc;
}, []);
console.log(unique); // ['apple', 'banana', 'orange']

优点 :逻辑直观,可灵活扩展。
缺点includes 也是遍历,时间复杂度 O(n²);同时 includes 能处理 NaN 但字符串场景无影响。


4. 利用对象/Map 作为哈希表(性能最优)

使用 Map 或普通对象记录已出现的元素,一次遍历即可,时间复杂度 O(n)。

javascript 复制代码
const arr = ['apple', 'banana', 'apple', 'orange', 'banana'];
const map = new Map();
const unique = arr.filter(item => {
  if (map.has(item)) return false;
  map.set(item, true);
  return true;
});
console.log(unique); // ['apple', 'banana', 'orange']

用对象也可以,但对象键会被转为字符串,对于纯字符串数组没问题,但若数组中包含数字或其他类型,需注意类型转换。

javascript 复制代码
const obj = {};
const unique = arr.filter(item => 
  obj.hasOwnProperty(item) ? false : (obj[item] = true)
);

优点 :线性时间复杂度,适合大数据量。
缺点:代码略复杂。


5. 进阶:保持首次出现顺序 + 去重

上述所有方法中,除了 Setfilter+indexOf 默认保持顺序,其余若稍加调整也能保持顺序。SetMap 本身也是按插入顺序迭代,因此上述基于 SetMap 的方案自然保持顺序。


总结

  • 日常开发 :推荐使用 [...new Set(arr)],代码最简洁,性能也不错。
  • 需要兼容极旧环境(如 IE) :可用 filter+indexOf
  • 大数据量且对性能有极致要求 :用 Map 哈希表方式。

注意,以上方法不仅适用于字符串数组,同样适用于数字、混合类型数组,但去重逻辑是基于严格相等(或 Set 的 SameValueZero)。对于对象数组,则需要根据对象的某个属性去重,以上方法需配合 map 提取属性值再进行去重。

相关推荐
小此方19 小时前
「C++AI大模型接入SDK」(一) API接入与本地两种方式对比、API Key获取、API报文详解与简单API的构建
开发语言·c++·人工智能
wuyk55520 小时前
Python实战项目02:学生成绩管理系统(控制台|CSV导出|完整落地)
开发语言·python
浪子明X1 天前
十六位账本怎样发现传输差错:Internet Checksum 生活类比
开发语言
尾善爱看海1 天前
Vue 面试收官篇:SSR、性能优化落地、30 道高频面试题精讲(附标准答案)
前端·javascript·vue.js·面试·vue
xiangyun611 天前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法
xiangyun611 天前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法
白远山1 天前
家政服务家政社区派单实战:调度系统架构设计与实现指南
java·开发语言·小程序·架构·需求分析
DevRay1 天前
Java 21虚拟线程深度实战:告别线程池焦虑,百万并发吞吐量直接翻倍(原理+代码+避坑)
java·开发语言
李明卫杭州1 天前
React 复合事件系统对比解析
前端·javascript·react.js
free-elcmacom1 天前
C++学习<1>程序分区
开发语言·c++