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

47 阅读4分钟

最后

在面试前我花了三个月时间刷了很多大厂面试题,最近做了一个整理并分类,主要内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

  • HTML5新特性,语义化

  • 浏览器的标准模式和怪异模式

  • xhtml和html的区别

  • 使用data-的好处

  • meta标签

  • canvas

  • HTML废弃的标签

  • IE6 bug,和一些定位写法

  • css js放置位置和原因

  • 什么是渐进式渲染

  • html模板语言

  • meta viewport原理

开源分享:docs.qq.com/doc/DSmRnRG… //并且走递归 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对象允许你存储任何类型(无论是[原始值](https://docs.qq.com/doc/DSmRnRGxvUkxTREhO)还是对象引用)的唯一值。



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 } //]

最后

资料过多,篇幅有限

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

自古成功在尝试。不尝试永远都不会成功。勇敢的尝试是成功的一半。