JS对象数组去重

news2025/1/17 3:04:54

JS对象数组去重

  • 一、数组去重
    • 1.使用 new Set()
    • 2.使用 indexOf 去重
    • 3.使用 includes 去重
    • 4.使用 hasOwnProperty
    • 5.使用 filter
    • 6.使用递归
    • 7.利用 Map 数据结构去重
    • 8.使用用 reduce + includes
    • 9.使用 new Set() 的简化
  • 二、对象数组去重
    • 1.使用 new Map() 和 filter
    • 2.使用reduce
    • 3.使用for循环
  • 总结


一、数组去重

有这样的一组数据:

let list = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];

1.使用 new Set()

Set 类型是一种叫做 集合 的数据结构,它是 无序的不可以重复的 集合,Set 集合是以 [值,值] 的形式存储元素;
Array.from() 可以将传入的字符串创建为一个数组。

function unique (arr) {
  // 利用Set不可重复的特性去重
  return Array.from(new Set(arr));
}

console.log(unique(list))
 // [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

打印控制台:
在这里插入图片描述

注意:不考虑兼容性,这种去重的方法代码最少,但这种方法还无法去掉 重复的 {} 空对象。

2.使用 indexOf 去重

新建一个空的结果数组,for 循环原数组,通过 indexOf 判断结果数组 是否存在当前元素,如果有相同的值则跳过,不相同则 push 进数组。

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    let result = [];
    for (let i = 0; i < result.length; i++) {
        if (result.indexOf(arr[i]) === -1) {
            result.push(arr[i])
        }
    }
    return result;
}

console.log(unique(list))
// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]  

注意:这种方法还无法去掉 重复的 {} 和 NaN 对象。

3.使用 includes 去重

基本思路与 利用 indexOf 去重是一样的,只不过判断结果数组是否存在当前元素方法调整为 includes() 方法。

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    let result = [];
    for (let i = 0; i < arr.length; i++) {
        if (!result.includes( arr[i])) {
            result.push(arr[i])
        }
    }
    return result;
}

console.log(unique(list))
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

注意:这种方法同样无法去掉{} 。

4.使用 hasOwnProperty

创建空对象存储数组值及其类型,再使用 hasOwnProperty 判断是否存在对象属性。

function unique(arr) {
	let obj = {};
	return arr.filter((item) => {
		return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
	})
}

console.log(unique(list))
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}] 

注意:所有的都去重了 。

5.使用 filter

使用 filter 遍历数组,使用 indexOf 判断当前元素在数组中的第一个索引是否和当前所引值相同,如果相同则证明之前没有重复的元素,可返回到结果数组中。

indexOf(searchValue, start)

  • searchvalue:必填,需检索的字符串值或者数组;
  • start: 可非必填,开始检索的位置,它的合法取值是 0 到 arr.length - 1,如省略该参数,则将从字符串的首字符开始检索。
function unique(arr) {
  return arr.filter(function(item, index, arr) {
    //当前元素,在原始数组中的第一个索引===当前索引值,否则返回当前元素
    return arr.indexOf(item, 0) === index;
  });
}

console.log(unique(list))
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}] 

注意:所有的都去重了 。

6.使用递归

利用 sort 函数对数组进行排序后,依次比较前后两个数据是否相等,若相等则将该数据从数组中删除。

function unique(arr) {
	// 1.复制数组和数组长度
	let arrCopy = [...arr];
	// 2.排序
	arrCopy.sort((a, b) => {
		return a - b;
	})
	// 3.利用递归比较临近两个值是否相等,若相等则删除;
    function loop(index) {
		if (index > 0) {
			if (arrCopy[index] === arrCopy[index - 1]) {
				arrCopy.splice(index, 1)
			}
			loop(index - 1)
 		}
    }
	loop(arr.length - 1);
    return arrCopy;
}

console.log(unique(list))
// [1, 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}]

注意:这种方法无法去掉 重复的 {} 对象。

7.利用 Map 数据结构去重

创建一个空 Map 数据结构,遍历需要去重的数组,把数组的每一个元素作为 key 存到 Map 中。由于 Map 中不会出现相同的 key 值,所以最终得到的就是去重后的结果。

function unique(arr) {
	// 1.创建一个空的 Map 数据
	let map = new Map();
	// 2.创建空数组,作为结果数组返回
	let resultArr = [];
	// 3.利用 map 对象判断数组中是否有相等的值
	for (let i = 0; i < arr.length; i++) {
		if(map.has(arr[i])){
			map.set(arr[i], true);
		}else{
            map.set(arr[i],false);
            resultArr.push(arr[i]);
        }
	}
	return resultArr;
}

console.log(unique(list))
// [1, 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}]

为了更好地理解,在控制台打印了下 map 对象:
在这里插入图片描述
注意:这种方法也无法去掉 重复的 {} 对象。

8.使用用 reduce + includes

reduce() 方法接收一个函数作为累加器,将数组中不包含的元素添加进来。

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

console.log(unique(list))
// [1, 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}]

注意:这种方法也无法去掉 重复的 {} 对象。

9.使用 new Set() 的简化

利用 set 集合不重复的特性,对数组进行去重并使用 […] 语法转化为数组格式,该方法其实就是方法1的简化。

let resultArr = [...new Set(list)];
console.log(resultArr);
// [1, 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}]

注意:这种方法也无法去掉 重复的 {} 对象。

由于以上方法大多无法去掉重复的 {} 对象,这边建议将对象类型的数据单独进行去重,先使用 Object.keys() 方法来获取对象属性的列表,然后再比较比较它们的值。

二、对象数组去重

对象数组结构如下所示:

// 原数据list是这样的                   // 去重后list数据是这样的
[{                                [{
  "tip_id": 1,                    	"tip_id": 1,
  "report_category": 0,             "report_category": 0,
  "remark": "已受理",                "remark": "已受理", 
},                                 },
{                                  {
  "tip_id": 2,                 		"tip_id": 2, 
  "report_category": 12,            "report_category": 12,
  "remark": "已处罚",                "remark": "已处罚",
},                                 }]
{
  "tip_id": 1, 
  "report_category": 0,  
  "remark": "已受理" 
}]

1.使用 new Map() 和 filter

Map 类型是 键值对有序 列表,而键和值都可以是任意类型。

function unique (arr, uniId) {
  const res = new Map();
  return arr.filter((item) => !res.has(item[uniId]) && res.set(item[uniId], 1));
}

let resultList = unique(list, "tip_id");
console.log(list); 

2.使用reduce

reduce() 方法对数组中的每个元素按序执行一个提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被用作初始值,迭代器将从第二个元素开始执行(即从索引为 1 而不是 0 的位置开始)。

function unique(arr, uniId) {
  let hash = {};
  return arr.reduce((accum, item) => {
    hash[item[uniId]] ? '' : hash[item[uniId]] = true && accum.push(item)
    return accum
  }, [])
}

let resultList = unique(list, "tip_id");
console.log(list);

3.使用for循环

基本思路和 reduce 是一样的,只不过是用 for 循环代替 reduce

function unique(arr, uniId) {
  let obj = {}
  let resultArr = []
  for(var i = 0; i < arr.length; i++) {
    if(!obj[arr[i][uniId]]) {
      resultArr.push(arr[i]);
      obj[arr[i][uniId]] = true;
    }
  }
  return resultArr;
}

let resultList = unique(list, "tip_id");
console.log(list);

总结

以上就是我总结的 数组去重对象数组去重 的 全部方法,后续如果想到更好的解决方案,也会记录在这里。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1047295.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为云HECS云服务器docker环境下安装nginx

前提&#xff1a;有一台华为云服务器。 华为云HECS云服务器&#xff0c;安装docker环境&#xff0c;查看如下文章。 华为云HECS安装docker-CSDN博客 一、拉取镜像 下载最新版Nginx镜像 (其实此命令就等同于 : docker pull nginx:latest ) docker pull nginx查看镜像 dock…

GB/T 14710-2009 医用电器环境要求及试验方法

举个例子&#xff1a; 应符合GB/T 14710-2009中气候环境试验II组&#xff0c;机械环境试验II组的要求。 气候环境试验II组&#xff0c;机械环境试验II组&#xff1f; 这是2个属性&#xff0c;先按特定的条件分组&#xff0c;分组后&#xff0c;应该满足该组的特定要求。这个标…

A+CLUB管理人支持计划第九期 | 仟富来资产

免责声明 本文内容仅对合格投资者开放&#xff01; 私募基金的合格投资者是指具备相应风险识别能力和风险承担能力&#xff0c;投资于单只私募基金的金额不低于100 万元且符合下列相关标准的单位和个人&#xff1a; &#xff08;一&#xff09;净资产不低于1000 万元的单位&…

为什么 SetWindowsHookEx 采用 HINSTANCE 参数?

有开发者问了这样一个问题&#xff1a;既然 SetWindowsHookEx 的第一个参数总是会被转换为一个文件名&#xff0c;那为什么它的传参类型是 HINSTANCE 呢&#xff1f;这岂不是多此一举&#xff1f; 原因是这样的&#xff1a;在 16 位 Windows 系统上&#xff0c;它不是这样工作…

MATLAB 与 Cruise 的联合仿真

文章目录 检查matlab是否安装了编译器在 MATLAB 中添加路径联合仿真示例 检查matlab是否安装了编译器 第一步&#xff0c;先检查matlab是否安装了编译器&#xff1a; 关于编译器的配置&#xff0c;可以查看&#xff1a; https://blog.csdn.net/chengkai730/article/details/1…

FPGA的数字钟带校时闹钟报时功能VHDL

名称&#xff1a;基于FPGA的数字钟具有校时闹钟报时功能 软件&#xff1a;Quartus 语言&#xff1a;VHDL 要求&#xff1a; 1、计时功能:这是数字钟设计的基本功能&#xff0c;每秒钟更新一次,并且能在显示屏上显示当前的时间。 2、闹钟功能:如果当前的时间与闹钟设置的时…

echarts强制显示或不显示Y轴最大值最小值

echarts强制显示或不显示Y轴最大值最小值 axisLabel: {showMaxLabel: false,color: "rgba(230,247,255,0.5)", //刻度线标签颜色fontSize: 14,formatter: function (value) {console.log(value);if (value / 2 % 10 0) {return value;} else {return }}},

mysql超级聚合with rollup

超级聚合&#xff0c;是在group by的基础上&#xff0c;再次进行聚合。 它再次聚合的列&#xff0c;是select中没有用到聚合函数的列。 文章目录 例子1解释例子2表以及数据 例子1 mysql> SELECT year, country, product, SUM(profit) AS profitFROM salesGROUP BY year, c…

Dev C++安装与运行

参考: https://blog.csdn.net/Keven_11/article/details/126388791 https://www.cnblogs.com/-Wallace-/p/cpp-stl.html 2021年真题要求 2022年真题要求 河南省的考试环境 IDE环境 Dev C 安装 下载 安装 点击OK&#xff0c;选择我接受 修改安装路径为D盘d:\Program Fi…

6.1810: Operating System Engineering Lab: Xv6 and Unix utilities By:Haostart

前言 开学后要为一年后找实习做准备了,准备打一下基础,就做一下MIT-6.S081,是2022版的,地址如下 6.1810: Operating System Engineering Lab Lab 做实验前一定要清楚Xv6的系统调用有哪些!!! 做实验前一定要清楚Xv6的系统调用有哪些!!! 1. sleep 由于系统调用里已经有slee…

MySQL 开启配置binlog以及通过binlog恢复数据

目录 一、binlog日志基本概念二、开启binlog日志记录2.1、查看binlog日志记录启用状态2.2、开启配置binlog日志 三、制作测试数据&#xff08;可以先不执行&#xff0c;这里是为后续数据恢复做准备&#xff0c;先看数据恢复流程&#xff09;四、使用binlog日志恢复数据4.1、前置…

解决内网拉取企微会话存档代理问题的一种办法

问题&#xff1a;客户的服务都是内网的&#xff0c;不能直接访问外网&#xff1b;访问外网的话需要走kong网关才能出去。 会话存档官网说可以使用socket5、http方式拉取会话存档&#xff1b;我这边尝试了直接使用kong网关的ip和端口配置进去&#xff0c;是访问不了的 我后面就…

lazada、shopee卖家自养号测评的优势及环境搭建核心要点!

lazada、shopee卖家们都知道&#xff0c;流量对于店铺转化率具有非常重要的作用&#xff0c;要真正提升销售业绩和品牌知名度&#xff0c;仅仅依赖lazada、shopee内部的流量是不够的。这也就说明越来越多的卖家需要测评&#xff0c;用测评来提升产品的销量&#xff0c;留下好评…

MYSQL日志和事务原理

1)重做日志:在一个事务中会涉及到多个DML操作&#xff0c;修改的是在内存层面数据页中的数据&#xff0c;还没有及时的将修改之后的数据更新到磁盘中&#xff0c;真正的将更新后的数据写回到磁盘的时候才满足持久性&#xff0c;只是更新内存是不满足持久性的&#xff0c;如果只…

lv5 嵌入式开发-8 内存映射

目录 1 内存映射基本使用 1.1 内存映射概念 1.2 内存映射的使用 2 共享内存&#xff08;古老的 System V IPC&#xff09; 2.1 基本概念 2.2 共享内存使用步骤 2.3 共享内存使用 掌握&#xff1a;内存映射概念、内存映射使用、内存映射注意事项、了解SYSTEM V 共享内存概…

OV2640图像出现细小条纹问题

说明&#xff1a;条纹是随机生成的&#xff0c;有时候几根线&#xff0c;有时候10多根线 怀疑点&#xff1a; 1-走线&#xff0c;看网上说所有的时钟线和同步线不要交叉&#xff0c;不要太长没有验证 2-电源&#xff0c;1.2V和2.8的电源 刚开始以为是自己电路问题&#xff0c…

栈(Stack)和队列(Queue)

栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;都是常见的数据结构&#xff0c;用于存储和操作一组元素。 栈是一种后进先出&#xff08;Last-In-First-Out&#xff0c;LIFO&#xff09;的数据结构&#xff0c;类似于把元素堆在一起形成的一堆物体&…

PTA程序辅助实验平台——2023年软件设计综合实践_3(分支与循环)

第一题&#xff1a;7-1 印第安男孩 - C/C 分支与循环 朵拉编程的时候也想顺便练习英语。她编程从键盘读入一个整数n&#xff0c;如果n值为0或者1&#xff0c;向屏幕输出“0 indian boy.”或“1 indian boy.”&#xff1b;如果n大于1&#xff0c;比如9&#xff0c;则输出“9 in…

Ctfshow web入门 XSS篇 web316-web333 详细题解 全

CTFshow XSS web316 是反射型 XSS 法一&#xff1a; 利用现成平台 法二&#xff1a; 自己搭服务器 先在服务器上面放一个接受Cookie的文件。 文件内容&#xff1a; <?php$cookie $_GET[cookie];$time date(Y-m-d h:i:s, time());$log fopen("cookie.txt"…

SSM - Springboot - MyBatis-Plus 全栈体系(十四)

第三章 MyBatis 二、MyBatis 基本使用 1. 向 SQL 语句传参 1.1 mybatis 日志输出配置 mybatis配置文件设计标签和顶层结构如下&#xff1a; configuration&#xff08;配置&#xff09; properties&#xff08;属性&#xff09;settings&#xff08;设置&#xff09;typeAl…