当前位置: 首页 > java >正文

JavaScript 数组去重:11 种方法对比与实战指南

文章目录

    • 前言
    • 一、使用 `Set` 数据结构
    • 二、使用 `filter` + `indexOf`
    • 三、使用 `reduce` 累加器
    • 四、双重 `for` 循环
    • 五、利用对象属性唯一性
    • 六、先排序后去重
    • 七、使用 `Map` 数据结构
    • 八、使用 `includes` 方法
    • 九、优化处理 `NaN` 的 `filter` 方法
    • 十、利用 `findIndex`
    • 十一.利用`Set`和展开运算符处理多维数组
    • 总结

前言

一、使用 Set 数据结构

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

利用 Set 数据结构中重复元素会被自动过滤的特点。

  • 优点:简单高效,时间复杂度为 O(n)。
  • 注意:无法区分对象引用类型,但是可以处理 NaN

二、使用 filter + indexOf

function uniqueByFilter(arr){return arr.filter((item,index)=> arr.indexOf(item) === index)
}

使用 indexOf 返回元素首次出现的索引,若非当前索引则过滤。

  • 注意:时间复杂度为 O(n²),不处理 NaN,因为 indexOf(NaN) 始终返回 -1。

三、使用 reduce 累加器

function uniqueByReduce(arr) {return arr.reduce((acc, cur) => acc.includes(cur) ? acc : [...acc, cur], []);
}

使用 reduce 检查当前元素是否存在于累加数组中,存在则不添加,不存在则添加。

  • 注意:时间复杂度为 O(n²),空间复杂度较高。

四、双重 for 循环

function uniqueByLoop(arr) {const result = [];for (let i = 0; i < arr.length; i++) {let isDuplicate = false;for (let j = 0; j < result.length; j++) {if (arr[i] === result[j]) {isDuplicate = true;break;}}if (!isDuplicate) result.push(arr[i]);}return result;
}

通过循环嵌套比较元素是否重复。

  • 注意:时间复杂度为 O(n²),性能较差。

五、利用对象属性唯一性

function uniqueByObj(arr){const obj = {}return arr.filter(item=>{const key = typeof item + JSON.stringify(item)return obj.hasOwnProperty(key) ? false :(obj[key] = true) })

对象的键名唯一,通过序列化来区分不同类型及对象。

  • 注意JSON.stringify 无法处理函数、循环引用,性能一般。

六、先排序后去重

function uniqueBySort(arr) {const sortedArr = [...arr].sort();return sortedArr.filter((item, index) => index === 0 || item !== sortedArr[index - 1]);
}

对数组排序后,重复的元素会相邻,然后直接过滤。

  • 注意:原数组顺序会被改变。

七、使用 Map 数据结构

function uniqueByMap(arr){const map = new Map()return arr.filter(item=>!map.has(item) && map.set(item,true))
}

利用 Map 键的唯一性可以快速判断元素是否存在。

  • 优点:时间复杂度为 O(n),可以正确处理对象引用和 NaN

八、使用 includes 方法

function uniqueByIncludes(arr) {const result = [];for (const item of arr) {if (!result.includes(item)) result.push(item);}return result;
}

在遍历时检查元素是否已存在于结果数组。

  • 注意:时间复杂度为 O(n²),不能处理 NaN

九、优化处理 NaNfilter 方法

function uniqueWithNaN(arr) {const hasNaN = arr.some(item => Number.isNaN(item));const result = arr.filter((item, index) => {if (Number.isNaN(item)) {// 仅保留第一个NaNreturn !hasNaN || (index === arr.findIndex(i => Number.isNaN(i)));}return arr.indexOf(item) === index;});return result;
}

单独处理 NaN,确保只保留第一个出现的 NaN

  • 优点:该方法兼容 NaN 去重。

十、利用 findIndex

function uniqueByFindIndex(arr) {return arr.filter((item, index) => {return arr.findIndex(i => i === item) === index;});
}

使用 findIndexindexOf 方法类似,但是可以处理自定义处理 NaN

十一.利用Set和展开运算符处理多维数组

function uniqueMultidimensionalArray(arr) {return Array.from(new Set(arr.flat(Infinity)));
}

首先利用flat方法将多维数组扁平化,然后利用Set去除重复元素,最后通过Array.fromSet转换会数组

  • 注意:该方法只能处理元素为基本类型或可序列化的对象的多维数组。如果数组中包含函数,循环引用等特殊对象,flat方法和Set可能无法正确处理

总结

  • 简单场景:优先使用 SetMap,简洁高效。
  • 兼容性要求:使用 filter + indexOf 或者双重循环。
  • NaN 或者对象:选择 Map 或改进的对象属性方法。
  • 排序无影响:排序后去重效率高 。
http://www.xdnf.cn/news/5275.html

相关文章:

  • 什么是 B2B?2B 产品销售怎么找客户?
  • Unity基础学习(十)Camera组件
  • [ctfshow web入门] web67
  • JVM对象创建内存分配
  • [特殊字符]️ 快速检测与修复TLS 1.0/1.1漏洞指南
  • 人形机器人:主控芯片
  • 红黑树算法笔记(二)性能对比实验
  • 解密数据结构之位图和布隆过滤器
  • TCP IP
  • 社区商城分销团长扩充与扩散策略优化的系统方案
  • Information Fusion期刊期刊投稿经验分享
  • 23、DeepSeekMath论文笔记(GRPO)
  • 计算机网络与多线程同步机制详解
  • Linux系统之----模拟实现shell
  • 轻量级因果语言视觉模型简述:nanoVLM-222M
  • 每日一题:两个仓库的最低配送费用问题
  • DNS负载均衡和CDN的区别
  • Redis 主从同步与对象模型(四)
  • 出现 SEGMENT: ?C_INITSEG 的原因:
  • ERP学习(一): 用友u8安装
  • 结合 ECharts / Ant Design Blazor 构建高性能实时仪表盘
  • smbd:快速拉取服務端SMB共享文件脚本工具
  • 从0开始学linux韦东山教程第三章问题小结(2)
  • 长短期记忆网络(LSTM)深度解析:理论、技术与应用全景
  • 每日算法刷题Day2 5.10:leetcode数组1道题3种解法,用时40min
  • MySQL索引详解(上)(结构/分类/语法篇)
  • Excel里面怎样批量去掉字串包含的标点符号
  • Qt解决自定义窗口样式不生效问题
  • 基于ssm+mysql的快递管理系统(含LW+PPT+源码+系统演示视频+安装说明)
  • Linux 离线安装 Docker 和 Docker Compose 最新版 的完整指南