面试前端数组去重,我会问这3个小问题_什么场合下需要使用数组去重

]


注意,因为每个人的博客或者是一个写作历程,必定是一个长时间发生的过程,所以数据一定是不定量的,可能还带有分页,所以服务端不可能预先将数据整理成前端需要的样子,所以这个时候,数据中的年月日部分便成了重复的需要去重的部分,去重后用于本案例汇总点的显示



#### 2、前端银行属地显示实例


有很多网站内有这样一个页面,银行属地显示,因为全国各地大大小小的银行有非常多,我们需要显示成这样:


![](https://img-blog.csdnimg.cn/2f5d546278f0464cbd6732f60cc53f99.png)


 很多时候,服务端也不会先将北京,天津,上海等属地给我们抽成map的key值形式,因为一些原因,也是以数组形式返回到前端,而这个数组大部分时候也是直接从数据库拉取的数据,这就导致需要我们前端做一些数组去重,服务端数据大概是这样子:



data = [
{
city: ‘北京’,
name: ‘北京银行1’
},
{
city: ‘北京’,
name: ‘北京银行2’
},
{
city: ‘北京’,
name: ‘XX商业银行’
},
{
city: ‘天津’,
name: ‘天津银行1’
},
{
city: ‘天津’,
name: ‘天津商业银行’
},
{
city: ‘天津’,
name: ‘港口商业银行’
},
]


这样一描述,类似场景想起来的是不是就很多了,这个案例中,数组内的city字段就是需要去重的对象。



### 二、说一下数组去重的几种实现方法吧



因为真实项目中,去重可能不仅仅是对一些数字的去重,可能还包含一些字符串,数字混合的场景,所以我们这里随意想一个混合数组,例如:


var arr = ['2022-03-21', 3, 8, 5, 3, 4, 3, '2022-03-21', '2022-03-22', 8];



#### 1、第1种


第1种是定义一个新的空数组,再执行嵌套双循环,监测空数组中如果没有的元素,push进空数组中。这个方法考察了continue的初级使用,也是一种思想,第一次空数组必定无内容,我们pus一个元素,跳过第一次循环,第二次再进行循环对比,代码如下:



var newArr = [];
for (var i=0;i<arr.length;i++) {
if (newArr.length === 0) {
newArr.push(arr[i]);
continue;
}
for (var j=0;j<newArr.length;j++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i]);
}
}
}


#### 2、第2种


第2种是第一种的改进,也是新定义一个空数组,利用indexOf监测新数组中是否包含某个元素,代码如下:



var newArr = [];
for (var i=0;i<arr.length;i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i]);
}
}


#### 3、第3种


第3种就是es6之后出的set了,set本身的设定就是非重复的类数组,所以才有了数组与set互相转换的知识点,而set转为数组可以是 [...set]这种解构形式,也可以是Array.from(set)的方法,代码如下:



var mySet = new Set(arr); // 非重复的类数组

// var newArr = Array.from(mySet); // set转数组
var newArr = […mySet]; // 或者是这种解构方法


#### 4、第4种


 利用filter的内置方法,filter接收一个内置函数,而函数自身又接收3个参数,item相当于arr[i],index相当于i索引,arr就是数组本身,某些情况需要传入arr,但本案例因为比较简单,就不传入了。利用indexOf首次查找索引的方式,返回原数组中元素首次出现的所有元素,达到去重效果,代码如下:



var newArr = arr.filter((item, index) => {
return arr.indexOf(item) === index;
})


#### 5、第5种


第5种是利用数组内置的includes方法,监测数组中是否包含某个元素,如果你在面试中说出这一条,证明你至少对数组的新属性,或者是一些内置方法做过整理,是个不错的回答,代码如下:



var newArr = [];
for (var i=0;i<arr.length;i++) {
if (!newArr.includes(arr[i])) {
newArr.push(arr[i]);
}
}


#### 6、第6种


第6种就是创建一个新的map(或者说是object)对象,利用其key值唯一的特性,不断的往map内创建属性,一旦某属性被创建过,那么就说明了可以对这个属性值做一些操作,而属性就已经是哪个去重的唯一元素了,代码如下:



var obj = {}; // 对象的key值是唯一的
var newArr = [];
for (var i=0;i<arr.length;i++) {
if (!obj[arr[i]]) {
obj[arr[i]] = arr[i];
}
}



### 三、你最喜欢用哪一种?



 数组去重不止这几种实现方法,对吧,那么你说出了那么多种,其实每次做项目的时候,某种场景下也就是用1种,不可能这个需求,我把每个都用了吧,那么你最喜欢用哪一种呢?


#### 我最早喜欢这个简单的


其实最早的时候,我喜欢第1种,因为那个时候技术实在是太辣鸡,不过想想现在也很辣鸡,所以很多时候我不敢输出干货,自己干货也不多,二来输出来了跟大家重复也挺高,那么多写知识点的,人家为啥就喜欢看我的呢。而且当时我还把第一种实现方法当做是瑰宝,四处跟人家显摆,屡试不爽,哈哈,不过后来我又看是用第二种了。


#### 现在喜欢这个object形式的


现在呢,我比较喜欢第6种,因为结合很多项目场景,其实开发过程中,很少有拿过来一个纯数组让去重的,大部分时候就像上面说到的案例,去重是为了解耦,将去重出来的部分做为一个大的key值,而value部分呢,有时候是一些子数组,有时候是更多的数组,所以我比较喜欢第6种,直接将原聚合数组,解开,然后处理成map对象形式,再在页面进行一些渲染。



### 四、分享一个我的案例


面试题这个东西是怎么出来的呢?是在大家慢慢工作中,不断遇到痛点,无数人总结出来的结果,慢慢发展成为了一道面试题,所以面试题的解法一般去网上查一查,背一背可以搞定。


但有一些面试官,你答的不顺利,他就想:你来面试,网上的答案那么多,你咋就不背一背呢?你答的太顺利,他又想:这货肯定是被答案了,跟网上说的如出一辙。


所以建议大家面试的时候,把面试题答案多结合一下自己的项目经验,把面试结果带入到项目经验中去解答,如果解答后呢,还能略微说一说自己遇到的问题,说一说自己的心得,那么我觉得面试官可能会为你的真诚打动一下吧。


#### **这里分享一个我曾经的成功案例:**



![img](https://img-blog.csdnimg.cn/img_convert/b925338c9c2a8d7f1d3378f170cdfea5.png)
![img](https://img-blog.csdnimg.cn/img_convert/b245dcbc7b7612d49ebc12539e024938.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值