【面试题】JS的14种去重方法,看看你知道多少(包含数组对象去重)

news2024/11/19 5:34:18

 前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

表妹一键制作自己的五星红旗国庆头像,超好看

前言

JavaScript数组是一种特殊的对象,用于保存多个值在一个连续的内存空间中,也正是因为如此,我们在数组中存储大量数据,但是巨大的数据量难免会有重复的,但我们并不需要重复的数据,这个时候就需要就数组进行去重,来达到每个数组都是唯一的,这样的数据才是我们想要的。

数组中值类型数据去重

使用sort去重

首先使用sort对数组排序,然后单循环判断

let arr = [1, 1, "2", "2", "string", "string", null, null, undefined, undefined];

arr.sort((a, b) => a - b);
for (let i = 0; i < arr.length; i++) {
//这里一定要多加一个条件,否者undfined就会被完全删除
  if (arr[i] === arr[i + 1] && i + 1 < arr.length) {
    arr.splice(i, 1);
    i--;
  }
}
console.log(arr);//[ null, 1, '2', 'string', undefined ]

使用递归去重

这种方法嘛,就是为了去重才去重的,可以使用,但完全不推荐

let arr = [1, "2", 1, "2", "string", null, "string", null, undefined, undefined];

//其实整体与第一种循环无异,只是利用了递归的特性
arr.sort((a, b) => a - b);
function recursion(index) {
  if (index >= 1) {
  //判断相同都会删除
    if (arr[index] === arr[index - 1]) {
      arr.splice(index, 1);
    }
    //并且走递归
    recursion(index - 1);
  }
}
recursion(arr.length - 1);

console.log(arr);//[ null, 1, '2', 'string', undefined ]

使用filter去重

filter都知道,条件成立就返回,这里主要是搭配了indexOf返回索引值的特性来实现的

let arr = [1, "2", 1, "2", "string", null, "string", null, undefined, undefined];

//整体感觉还挺简单,就是indexOf会返回所符合条件的第一个值索引值,然后就会跳出循环
//所以每个数只能有一次与filter的index相同
arr = arr.filter((item, index) => {
  return arr.indexOf(item) === index;
});
console.log(arr);//[ 1, '2', 'string', null, undefined ]

使用对象属性去重

我们都知道对象的属性有且只能有一个,我们就可以利用这个特性,来对数组中的值去重

let arr = [1, "2", 1, "2", "string", null, "string", null, undefined, undefined];

const obj = {};
const newArr = [];
arr.forEach((item) => {
//对象的值没有赋值之前默认undfined,所以为假,会走进判断
//当再次遇到这个属性的时候已经有值了,并且为真,则会跳过
  if (!obj[item]) {
    obj[item] = true;
    newArr.push(item);
  }
});

console.log(newArr);//[ 1, '2', 'string', null, undefined ]

使用reduce和includes去重

reduce这个方法搭配includes,可以简便快捷的去重(这里reduce方法都会的吧)

let arr = [1, "2", 1, "2", "string", null, "string", null, undefined, undefined];

arr = arr.reduce((prev, cur) => {
//当prev种不存在当前循环遍历的值,就会执行push操作,如果存在,那就存在呗,没事了
  prev.includes(cur) || prev.push(cur);
  return prev;
}, []);

console.log(arr);//[ 1, '2', 'string', null, undefined ]

使用reduce和indexOf去重

这一种跟配合indexOf是类似差不多了,当indexOf找不到就会返回-1

let arr = [1, "2", 1, "2", "string", null, "string", null, undefined, undefined];

arr = arr.reduce((prev, cur) => {
//这里当为真了,就会执行后面的push,上面那种就是当为假了 就会执行后面push
  prev.indexOf(cur) === -1 && prev.push(cur);
  return prev;
}, []);

console.log(arr);//[ 1, '2', 'string', null, undefined ]

双重循环去重

利用两个for循环,进行对比来达到去重的效果

let arr = [1, "2", 1, "2", "string", null, "string", null, undefined, undefined];

for (let i = 0; i < arr.length; i++) {
  for (let j = i + 1; j < arr.length; j++) {
  //利用两层循环,对比是否有相同的值
    if (arr[i] === arr[j]) {
      arr.splice(j, 1);
      //删除值后-1,否者会跳过一个元素
      j--;
    }
  }
}

console.log(arr);//[ 1, '2', 'string', null, undefined ]

使用indexof去重

这个就是利用indexOf的特性去重,当为-1的时候才会新填元素

let arr = [1, "2", 1, "2", "string", null, "string", null, undefined, undefined];

const newArr = [];
for (let i = 0; i < arr.length; i++) {
  if (newArr.indexOf(arr[i]) === -1) {
  //找不到就添加,找到了就证明已经有了,就略过
    newArr.push(arr[i]);
  }
}

console.log(newArr);//[ 1, '2', 'string', null, undefined ]

使用Set去重

Set对象允许你存储任何类型(无论是原始值还是对象引用)的唯一值。

let arr = [1, "2", 1, "2", "string", null, "string", null, undefined, undefined];

//所以就可以利用扩展运算符和new Set 来进行去重
arr = [...new Set(arr)];

console.log(newArr);//[ 1, '2', 'string', null, undefined ]

数组对象去重

在开发中我们很少遇到值类型的数组需要去重,一般情况下都是数组包对象的形式,但是当数组中的对象有重复的时候,该如何去重呢?毕竟作为引用类型的对象,每一个都是唯一的

利用对象的特性对数组对象去重

使用循环,利用对象的特性进行去重

const arr = [
  { id: 1, name: "张三", age: 18 },
  { id: 2, name: "李四", age: 13 },
  { id: 3, name: "张三", age: 15 },
  { id: 2, name: "王五", age: 16 },
  { id: 4, name: "赵六", age: 18 },
];

const obj = {};
const newArr = [];
arr.forEach((item) => {
//循环遍历,判断对象属性是否为真,为假就将数据添加到新数组中
  obj[item.id] ? "" : (obj[item.id] = true && newArr.push(item));
});
console.log(newArr);
//[
//  { id: 1, name: '张三', age: 18 },
//  { id: 2, name: '李四', age: 13 },
//  { id: 3, name: '张三', age: 15 },
//  { id: 4, name: '赵六', age: 18 }
//]

利用findIndex对数组对象去重

数组有个findIndex方法,会循环遍历,return真的时候会返回当前索引,找不到就返回-1

const arr = [
  { id: 1, name: "张三", age: 18 },
  { id: 2, name: "李四", age: 13 },
  { id: 3, name: "张三", age: 15 },
  { id: 2, name: "王五", age: 16 },
  { id: 4, name: "赵六", age: 18 },
];

const newArr = [];
arr.forEach((item) => {
  if (newArr.findIndex((item1) => item1.id === item.id) === -1) {
    newArr.push(item);
  }
});
console.log(newArr);
//[
//  { id: 1, name: '张三', age: 18 },
//  { id: 2, name: '李四', age: 13 },
//  { id: 3, name: '张三', age: 15 },
//  { id: 4, name: '赵六', age: 18 }
//]

使用reduce对数组对象去重

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

const arr = [
  { id: 1, name: "张三", age: 18 },
  { id: 2, name: "李四", age: 13 },
  { id: 3, name: "张三", age: 15 },
  { id: 2, name: "王五", age: 16 },
  { id: 4, name: "赵六", age: 18 },
];

const obj = {};
//跟单遍历循环去重差不多,只是少定义了一个新的数组,主要还是对数组方法的使用
const newArr = arr.reduce((pre, cur) => {
  obj[cur.id] ? "" : (obj[cur.id] = true && pre.push(cur));
  return pre;
}, []);
console.log(newArr);
//[
//  { id: 1, name: '张三', age: 18 },
//  { id: 2, name: '李四', age: 13 },
//  { id: 3, name: '张三', age: 15 },
//  { id: 4, name: '赵六', age: 18 }
//]

双重循环对数组对象去重

双重循环去重和值类型去重类似,相互对比他们的id来达到去重的效果

const arr = [
  { id: 1, name: "张三", age: 18 },
  { id: 2, name: "李四", age: 13 },
  { id: 3, name: "张三", age: 15 },
  { id: 2, name: "王五", age: 16 },
  { id: 4, name: "赵六", age: 18 },
];

for (let i = 0; i < arr.length; i++) {
  for (let j = i + 1; j < arr.length; j++) {
    if (arr[i].id === arr[j].id) {
      arr.splice(j, 1);
      j--;
    }
  }
}
console.log(arr);
//[
//  { id: 1, name: '张三', age: 18 },
//  { id: 2, name: '李四', age: 13 },
//  { id: 3, name: '张三', age: 15 },
//  { id: 4, name: '赵六', age: 18 }
//]

使用递归对数组对象去重

递归去重,跟值类型去重类似,操作方法也是类似的,当然也是不推荐使用的

const arr = [
  { id: 1, name: "张三", age: 18 },
  { id: 2, name: "李四", age: 13 },
  { id: 3, name: "张三", age: 15 },
  { id: 2, name: "王五", age: 16 },
  { id: 4, name: "赵六", age: 18 },
];

const obj = {};
const newArr = [];
function recursion(v) {
  if (v >= 0) {
    if (!obj[arr[v].id]) {
      obj[arr[v].id] = true;
      newArr.push(arr[v]);
    }
    recursion(v - 1);
  }
}
recursion(arr.length - 1);
console.log(newArr);
//[
//  { id: 4, name: '赵六', age: 18 },
//  { id: 2, name: '王五', age: 16 },
//  { id: 3, name: '张三', age: 15 },
//  { id: 1, name: '张三', age: 18 }
//]

结尾

数组去重在生产中是必不可少的操作,当获取到大量数据的时候,必定会有重复的数据,后端处理不好,只能由前端来进行处理,方法虽然比较多,虽然上面说了14种去重方式,但有些方法都差不多,适合自己的最好,只要会一种去重方式,就能解决99%的场景需求。

 前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

 表妹一键制作自己的五星红旗国庆头像,超好看

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

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

相关文章

Linux 进程层次分析

Linux 进程组 每个进程都有一个进程组号 (PGID) 进程组&#xff1a;一个或多个进程的集合 (集合中的进程并不孤立)进程组中的进程通常存在父子关系&#xff0c;兄弟关系&#xff0c;或功能相近 进程组可方便进程管理 (如&#xff1a;同时杀死多个进程&#xff0c;发送一个信…

第57篇-某手did滑块流程分析【2023-09-25】

声明:该专栏涉及的所有案例均为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖! 文章目录 一、前言二、滑块流程分析三、参数分析1.verifyParam参数分析2.c参数分析四、captchaToken激活五、流程整理一、前言 我…

vSAN数据恢复-vSAN架构下虚拟机磁盘组件出现问题的数据恢复案例

vsan数据恢复环境&#xff1a; 一套VMware vSAN超融合基础架构&#xff0c;全闪存&#xff0c;开启压缩重删。共11台服务器节点。每台服务器节点上配置1块PCIE固态硬盘和8-10块SSD固态硬盘。 每个服务器节点上创建1个磁盘组&#xff0c;每个磁盘组将1个PCIE固态硬盘识别为2个硬…

去重的数组模拟

输入&#xff1a; 10 20 40 32 67 40 20 89 300 400 15 输出&#xff1a; 8 15 20 32 40 67 89 300 400 #include<bits/stdc.h> using namespace std;typedef long long ll;const int N 2e55;int main(){int n;cin>>n;int a[N];for(int i1;i<n;i){cin>>a…

数据统计和分析怎么做?spss如何做好数据分析?

为什么要做数据分析?数据分析有什么意义&#xff1f;数据分析可以为企业和组织提供多方面的帮助&#xff0c;包括提高工作效率、优化业务流程、升职加薪、提高管理效率以及改进汇报效果等方面。 IBM SPSS Statistics 26是一款功能强大的统计分析软件&#xff0c;适用于Mac操作…

【办公自动化】使用Python一键往Word文档的表格中填写数据(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

DirectX 12 学习笔记 -结构

上篇文章我们创建了一个窗口&#xff0c;看样子还不难&#xff0c;我们继续玩DX12 引用一些文件 头文件 #include <d3d12.h> #include <dxgi1_4.h> #include <wrl.h>还有一些库 #pragma comment(lib, "d3d12.lib") #pragma comment(lib, "…

【择校宝典】80所院校择校汇总更新!

截止目前为止&#xff0c;我已发布近。80所院校的择校分析&#xff0c;102所名校真题。139所重点勾画 哈喽大家好&#xff0c;之前答应大家&#xff0c;在报考之前汇总择校分析。告诉大家我发现的规律&#xff0c;辅助大家报考&#xff0c;绝不食言&#xff01; 千呼万唤始出…

【好玩的开源项目】Windows 12网页版的部署与使用体验

【好玩的开源项目】Windows 12网页版的部署与使用体验 一、Windows 12网页版介绍1.1 Windows 12网页版简介1.2 项目地址 二、本次实践介绍2.1 本地环境规划2.2 本次实践介绍 三、安装httpd软件3.1 检查yum仓库3.2 安装httpd软件3.3 启动httpd服务3.4 查看httpd服务3.5 防火墙和…

历史高频行情数据存储最佳实践:DolphinDB Array Vector 使用指南

越来越多的机构使用 L1/L2 的快照行情数据进行量化金融的研究。作为一个高性能时序数据库&#xff0c;DolphinDB 非常适合存储和处理海量的历史高频行情数据。针对快照数据包含多档位信息的特点&#xff0c;DolphinDB 研发了一种方便、灵活且高效的数据结构——Array Vector&am…

【李沐深度学习笔记】基础优化方法

课程地址和说明 基础优化方法p2 本系列文章是我学习李沐老师深度学习系列课程的学习笔记&#xff0c;可能会对李沐老师上课没讲到的进行补充。 基础优化方法 在讲具体的线性回归实现之前&#xff0c;要先讲一下基础的优化模型的方法 梯度下降 当模型没有显示解&#xff08…

比较身高-第15届蓝桥杯第一次STEMA测评Scratch真题精选

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第153讲。 第15届蓝桥杯第1次STEMA测评已于2023年8月20日落下帷幕&#xff0c;编程题一共有6题&#xff0c;分别如下&a…

【HUAWEI】trunk和access两种链路模式实例

目录 &#x1f96e;0.写在前面 &#x1f363;基本操作命令 &#x1f363;常见视图命令 &#x1f96e;1、trunkaccess &#x1f363;1.1、拓扑图 &#x1f363;1.2、操作思路 &#x1f363;1.3、配置操作 &#x1f361;1.3.1、LSW1配置 &#x1f361;1.3.2、LSW2配置 &#x1f3…

Android Key/Trust Store研究+ssl证书密钥

前言&#xff1a;软件搞环境涉及到了中间件thal trustzone certificate key&#xff0c;翻译过来是thal信任区域证书密钥 &#xff0c;不明白这是什么&#xff0c;学习一下 ssl证书密钥 SSL密钥是SSL加密通信中的重要组成部分。SSL证书通过加密算法生成&#xff0c;用于保护网…

sgx支持数据库环境配置,编译,debug

环境都编译为debug模式&#xff0c;为了开发&#xff0c;并利用sgx的debugger sgx-gdb进行debug 查看cpu是否支持sgx delldell-Precision-3630-Tower  /nvme  lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte…

AUTOSAR中的Crypto Stack(一)--概述

前面我们聊到了比较多的关于信息安全的概念,以及主流MCU的信息安全方案。但从软件工程师的角度来看,最终这些信息安全的概念都是会从软件来实现;如何设计出一种合理、安全的信息安全软件框架,我们从AUTOSAR的加密栈来分析。 该协议栈主要从以下几个方面来介绍: AUTOSAR中…

蓝桥杯打卡Day15天

文章目录 买不到的数目错误票据 一、买不到的数目OJ链接 本题思路:引理&#xff1a;给定a&#xff0c;b&#xff0c;若dgcd(a,b)>1 ,则一定不能凑出最大数。结论&#xff1a;如果 a,b均是正整数且互质&#xff0c;那么由 axby,x≥0,y≥0 不能凑出的最大数是 ab−a−b。 证…

Bigemap如何查看历史影像

工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP 很多人都在寻找历史影像图&#xff0c;这块的需求是非常大&#xff0c;历史影像一般可以用于历史地貌的变迁分析&#xff0c;还原以前的生态场景&#xff0c;对范围面积…

深入探讨Vue.js:从基础到高级(最佳实践)

文章目录 Vue.js 基础1. Vue.js 是什么&#xff1f;2. Vue 实例3. 双向数据绑定 Vue 组件1. 什么是 Vue 组件&#xff1f;2. 组件之间的通信 Vue 模板语法1. 插值和指令2. 条件和循环3. 事件绑定和表单输入绑定 Vue 路由1. Vue Router安装和配置&#xff1a;导航&#xff1a; 2…

企业做软文推广的三大错误有哪些?媒介盒子为您解答

软文营销已经成为企业宣传的主要方式&#xff0c;但有很多企业来找媒介盒子咨询&#xff0c;明明花了大量成本来做软文推广&#xff0c;为什么就是没效果呢&#xff1f;小编看了下&#xff0c;发现大部分企业做软文推广效果不明显&#xff0c;基本上犯了三大错误&#xff0c;接…