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 版本来显示网页. 注意: 声明位于文档中的最前面的位置,处于 标签之前。 …...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...