JS 数组去重的方法
// 数组去重
const arr = ["1", "1", "2", "3", "5", "3", "1", "5", "4"]
console.log(this.deduplicate(arr)) // ['1', '2', '3', '5', '4']
// 数组对象去重
const arr = [
{ id: 1, name: "数据1" },
{ id: 1, name: "数据2" },
{ id: 2, name: "数据3" },
{ id: 3, name: "数据4" },
{ id: 4, name: "数据5" },
{ id: 3, name: "数据6" },
{ id: 5, name: "数据7" }
]console.log(this.deduplicate(arr, "id")) // [{ id: 1, name: "数据2" }, { id: 2, name: "数据3" }, { id: 3, name: "数据4" }, { id: 4, name: "数据5" }, { id: 5, name: "数据7" }]
方法一
/** 数组去重* 思路:定义一个新数组,存放原数组的第一个元素,然后将原数组和新数组的元素对比,若不同则存放在新数组中* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {const newArr = [arr[0]]// 有指定字段if (t) {for (let i = 1; i < arr.length; i++) {let repeat = falsefor (let j = 0; j < newArr.length; j++) {if (t && arr[i][t] === newArr[j][t]) {repeat = truebreak}}if (!repeat) newArr.push(arr[i])}}// 无指定字段else {for (let i = 1; i < arr.length; i++) {let repeat = falsefor (let j = 0; j < newArr.length; j++) {if (arr[i] === newArr[j]) {repeat = truebreak}}if (!repeat) newArr.push(arr[i])}}return newArr
}
方法二
/** 数组去重* 思路:先将原数组进行排序,再与相邻的角标进行对比,如果不同则存入新数组* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {const sortArr = arr.sort(function (a, b) {if (t) return a[t] - b[t]return a - b}), // 升序排列newArr = [sortArr[0]]// 有指定字段if (t) {for (let i = 1; i < sortArr.length; i++) {if (sortArr[i][t] !== sortArr[i - 1][t]) newArr.push(sortArr[i])}}// 无指定字段else {for (let i = 1; i < sortArr.length; i++) {if (sortArr[i] !== sortArr[i - 1]) newArr.push(sortArr[i])}}return newArr
}
方法三
/** 数组去重* 思路:利用对象属性存在的特性,如果没有该属性则存入新数组* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {const obj = {},newArr = []// 有指定字段if (t) {for (let i = 0; i < arr.length; i++) {if (!obj[arr[i][t]]) {obj[arr[i][t]] = 1newArr.push(arr[i])}}}// 无指定字段else {for (let i = 0; i < arr.length; i++) {if (!obj[arr[i]]) {obj[arr[i]] = 1newArr.push(arr[i])}}}return newArr
}
方法四
/** 数组去重* 思路:利用数组的 indexOf 下标属性来查询* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {const newArr = [],assignList = []// 有指定字段if (t) {for (let i = 0; i < arr.length; i++) {if (assignList.indexOf(arr[i][t]) === -1) {assignList.push(arr[i][t])newArr.push(arr[i])}}}// 无指定字段else {for (let i = 0; i < arr.length; i++) {if (newArr.indexOf(arr[i]) === -1) newArr.push(arr[i])}}return newArr
}
方法五
/** 数组去重* 思路:利用数组原型对象上的 includes 方法* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {const newArr = [],assignList = []// 有指定字段if (t) {for (let i = 0; i < arr.length; i++) {if (!assignList.includes(arr[i][t])) {assignList.push(arr[i][t])newArr.push(arr[i])}}}// 无指定字段else {for (let i = 0; i < arr.length; i++) {if (!newArr.includes(arr[i])) newArr.push(arr[i])}}return newArr
}
方法六
/** 数组去重* 思路:利用数组原型对象上的 filter 和 includes 方法* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {let newArr = []// 有指定字段if (t) {newArr = arr.filter(function (item) {return newArr.includes(item[t]) ? "" : newArr.push(item[t])})}// 无指定字段else {newArr = arr.filter(function (item) {return newArr.includes(item) ? "" : newArr.push(item)})}return newArr
}
方法七
/** 数组去重* 思路:利用数组原型对象上的 forEach 和 includes 方法* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {const newArr = [],assignList = []// 有指定字段if (t) {arr.forEach(item => {if (!assignList.includes(item[t])) {assignList.push(item[t])newArr.push(item)}})}// 无指定字段else {arr.forEach(item => {return newArr.includes(item) ? "" : newArr.push(item)})}return newArr
}
方法八
/** 数组去重* 思路:利用数组原型对象上的 splice 方法* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {let i,j,len = arr.length// 有指定字段if (t) {for (i = 0; i < len; i++) {for (j = i + 1; j < len; j++) {if (arr[i][t] === arr[j][t]) {arr.splice(j, 1)len--j--}}}}// 无指定字段else {for (i = 0; i < len; i++) {for (j = i + 1; j < len; j++) {if (arr[i] === arr[j]) {arr.splice(j, 1)len--j--}}}}return arr
}
方法九
/** 数组去重* 思路:利用数组原型对象上的 lastIndexOf 方法* @param arr 需要去重的数组* @param t 根据 t 字段(指定)进行去重* @returns {*[]} 已去重后的数据*/
deduplicate(arr, t = "") {const newArr = [],assignList = []// 有指定字段if (t) {for (let i = 0; i < arr.length; i++) {if (assignList.lastIndexOf(arr[i][t]) === -1) {assignList.push(arr[i][t])newArr.push(arr[i])}}}// 无指定字段else {for (let i = 0; i < arr.length; i++) {newArr.lastIndexOf(arr[i]) !== -1 ? "" : newArr.push(arr[i])}}return newArr
}
相关文章:
JS 数组去重的方法
// 数组去重 const arr ["1", "1", "2", "3", "5", "3", "1", "5", "4"] console.log(this.deduplicate(arr)) // [1, 2, 3, 5, 4] // 数组对象去重 const arr [ { id: 1, nam…...

PMP项目管理项目沟通管理
目录1 项目沟通管理2 规划沟通管理3 管理沟通4 监督沟通1 项目沟通管理 项目沟通管理包括通过开发工件,以及执行用于有效交换信息的各种活动,来确保项目及其相关方的信息需求得以满足的各个过程。项目沟通管理由两个部分组成:第一部分是制定…...

2.JVM常识之 运行时数据区
1.JVM核心组成 2.JVM 运行时数据区(jdk8) 程序计数器:线程私有,当前线程所执行字节码的行号指示器 jvm栈:线程私有,Java 虚拟机栈为 JVM 执行 Java 方法服务 本地方法栈:线程私有,本…...

你的游戏帐号是如何被盗的
据报道,2022上半年,中国游戏市场用户规模达到了5.54亿人,游戏市场销售收入1163.1亿元,相较去年均为同比增长的情况。如此庞大的市场规模,黑色产业链是绕不开的话题。 但相较于游戏中大家常见的玩家与玩家、玩家与官方…...

C++11异步编程
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言1、std::future和std::shared_future1.1 std:future1.2 std::shared_future2、std::async3、std::promise4、std::packaged_task前言 C11提供了异步操作相关的类…...
20230310----重返学习-DOM元素的操作-时间对象-定时器
day-024-twenty-four-20230310-DOM元素的操作-时间对象-定时器 复习 获取元素 id document.getElementById() 类名 document.getElementsByClassName() 标签名 document.getElementsByTagName() name属性 document.getElementsByName() 选择器 document.querySelector()docum…...

江苏专转本转本人后悔排行榜
江苏专转本转本人后悔排行榜 一、复习的太迟: 后悔指数:五颗星。 复习越到最后,时间一天天变少,要复习的内容还有很多,很多人都后悔没有早早开始,总想着多给我两月一定会考上的。 担心时间不够用,那就努力利…...

【算法时间复杂度】学习记录
最近开算法课,开几篇文章记录一下算法的学习过程。 关于算法的重要性 学习计算机当程序员的话,在编程过程中是绕不开算法这个大矿山的,需要我们慢慢挖掘宝藏。 算法(Algorithm)是指用来操作数据、解决程序问题的一组…...
汽车车机芯片Linux系统内核编译问题总结
谈到车机,很多人会想到华为问界上装的大屏车机,号称车机的天花板,基于鸿蒙OS的,而今天谈到的车机芯片用的是linux内核Kernel,对于它的编译,很多人一时会觉得头大,的确如果工具不是很齐全,就会遇到这样那样的问题,但是过程都会有错误提示,按照错误提示基本可以解决,而…...
Android13 音量曲线调整
Android13 音量曲线调整 Android13 上配置文件的路径: /vendor/sprd/modules/audio/engineconfigurable_apm/工程目录/system/etc/audio_engine_config/audio_policy_engine_stream_volumes.xml /vendor/sprd/modules/audio/engineconfigurable_apm/工程目录/sys…...

OpenHarmony通过MQTT连接 “改版后的华为IoT平台”
一、前言 本篇文章我们使用的是BearPi-HM_Nano开发板:小熊派的主板+E53_IA1扩展板 源码用的是D6_iot_cloud_oc,点击下载BearPi-HM_Nano全量源码 那么为什么要写这篇呢? 前段时间看到OpenHarmony群里,经常有小伙伴问接入华为IoT平台的问题,他们无法正常连接到华为IoT平台等…...

SQS (Simple Queue Service)简介
mazon Simple Queue Service (SQS)是一种完全托管的消息队列服务,可以让你分离和扩展微服务、分布式系统和无服务应用程序。 在讲解SQS之前,首先让我们了解一下什么是消息队列。 消息队列 还是举一个电商的例子,一个用户在电商网站下单后付…...
高速PCB设计指南系列(三)
第一篇 高密度(HD)电路的设计 本文介绍,许多人把芯片规模的BGA封装看作是由便携式电子产品所需的空间限制的一个可行的解决方案,它同时满足这些产品更高功能与性能的要求。为便携式产品的高密度电路设计应该为装配工艺…...

【C++】C++11——左右值|右值引用|移动语义|完美转发
文章目录一、左值与右值1.概念2.引用3.注意二、右值引用的意义1.左值引用意义2.右值引用和移动语义3.容器新增三、万能引用四、完美转发一、左值与右值 1.概念 左值是什么?右值是什么? 左值是一个表示数据的表达式(如变量名或解引用的指针&…...

[ROC-RK3399-PC Pro] 手把手教你移植主线Buildroot(基于2023.02-rc3版本)
🍇 博主主页:Systemcall小酒屋🍇 博主简介:Neutionwei,C站嵌入式领域新星创作者之一,一枚热爱开源技术、喜欢分享技术心得的极客,注重简约风格,热衷于用简单的案例讲述复杂的技术&am…...
重温线性代数
前言 对于普通的数学工作者而言,掌握矩阵、线性空间的基本性质和用法比领会抽象的概念更实用。数学专业的同学需要全面深入学习近世代数的理论和演绎法则,例如模的概念和运算。 总之,我个人认为,不论是微积分、还是线性代数&…...

2023河北沃克HEGERLS甘肃金昌重型仓储项目案例|托盘式四向穿梭车智能密集存储系统在工业行业的创新应用
项目名称:自动化仓储托盘式四向穿梭车智能密集立体库项目 项目合作客户:甘肃省金昌市某集团企业 项目施工地域:甘肃省金昌市 设计与承建单位:河北沃克金属制品有限公司(自主品牌:海格里斯HEGERLS&#x…...

软件测试的案例分析 - 闰年5
文章目的 显示不同的博客能获得多少博客质量分 (这是关于博客质量分的测试 https://www.csdn.net/qc) 这个博客得了 83 分。怎么才能得到更多分数? 正文 我们谈了不少测试的名词, 软件是人写的, 测试计划和测试用例也是人写的, 人总会犯错误。错误发生…...

Linux文件基础I/O
文件IO文件的常识基础IO为什么要学习操作系统的文件操作C语言对于函数接口的使用接口函数介绍如何理解文件文件描述符重定向更新给模拟实现的shell增加重定向功能为什么linux下一切皆文件?文件的常识 1.空文件也要在磁盘占据空间 2.文件 内容 属性 3.文件操作 对…...

HTML看这一篇就够啦,HTML基础大全,可用于快速回顾知识,面试首选
HTML 1 基础 1.1 DOCTYPE <!DOCTYPE> 文档类型声明,作用就是告诉浏览器使用哪种HTML版本来显示网页。 <!DOCTYPE html> 这句代码的意思是: 当前页面采取的是 HTML5 版本来显示网页. 注意: 声明位于文档中的最前面的位置,处于 标签之前。 …...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...