面试必备!数组去重的 6 种方法

在前端的面试或笔试中,经常会碰到让你写一段数组去重的代码,今天就带大家一起来学习数组去重的 6 个方法,所谓人无我有,人有我优。当别人掌握了一两种方法时,你就要努力掌握比别人更多的方法,这样就可以让自己更有竞争力些。

直接遍历法

这种方法直接遍历数组,利用 JavaScript 的 indexOf 方法,新建一个新数组,用这个数组去判断旧数组中的每一个数是否等于-1,如果是,说明该数在新数组中不存在,则将其添加进新数组,遍历完后就能将数组去重并保存至新建的数组中。这里要解释一下Array.prototype.indexOf()方法,mozilla 给出该方法的作用是The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.了解了它的含义后就可以开始写以下的函数:

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

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort1(arr));    // 1, 5, 9, null, undefined

reduce 函数

使用数组的 reduce 方法在结合 indexOf 两个方法同样能去重。mozilla 官方对 reduce 的解释是 arr.reduce(callback[, initialValue]) 方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。简单点讲就是对数组中的每一个数作用一个函数,这个回调函数就是第一个参数 callback ,第二个参数是传入的初始值,不传则使用数组中的第一个元素,注意在没有初始值的空数组上调用 reduce 将报错。

function oSort2(arr){
  return arr.reduce(function(prev,next){
    if(prev.indexOf(next) === -1){
      prev.push(next);
    }
    return prev;
  }, []);
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort2(arr));    // 1, 5, 9, null, undefined

相邻比较

这种方法利用数组的 sort() 函数,这个函数原本是对数组进行排序的,但在这里我们不用它进行排序,而只是让它将重复的元素聚拢起来,接着我们比较相邻的两个数,如果相等,则跳过;如果不相等,我们就将其添加进新数组里,这样得到的数组就是去重后的数组。

function oSort3(arr){
  var newArr = [arr[0]];
  arr.sort();
  for(var i=1;i<arr.length;i++){
    if(arr[i] !== arr[i-1]){
      newArr.push(arr[i]);
    }
  }
  return newArr;
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort3(arr));    // 1, 5, 9, null, undefined

这里为了简便,直接将第一个元素添加进新数组,然后循环 i 从 1 开始,也就是从第二个数开始遍历直到结束。

下标指针遍历

第四种方法是利用数组的下标指针,来确定是否是相同的元素,如果是的话,就让其指针递增跳过,然后不断把不重复的数组保存至新数组中。来看如下代码:

function oSort4(){
  var newArr = [];
  for(var i=0;i<arr.length;i++){
    for(var j=i+1;j<arr.length;j++){
      if(arr[i] === arr[j]){
        j = ++i;
      } 
    }
    newArr.push(arr[i]);
  }
  return newArr;
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort4(arr));  // 1, 9, null, 5, undefined

上面的代码嵌套了两层循环,分别有 i 和 j 两指针,其中 j 总是比 i 大 1,通过判断数组中这个数与它后面的数是否相等,如果相等,则说明这个数重复了,我们便将指针 i 和 j 继续往后运行,然后用 j = ++i 保持 j 比 i 大 1。最后一直把不重复的指针 i 对应的元素添加进数组。

临时对象存储

借用一个临时对象来存储数组元素,判断数组中的元素是否在对象中,如果不存在,就将该数添加进数组,并在临时对象中做标记。

function oSort5(arr){
  var newArr = [];
  var temp = {};
  for(var i=0;i<arr.length;i++){
    if(!temp[arr[i]]){
      newArr.push(arr[i]);
      temp[arr[i]] = true;
    }
  }
  return newArr;
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort5(arr));   // 1, 5, 9, null, undefined

简单粗暴法

这种方法厉害了,只需要一句代码:

function oSort6(arr){
  return Array.from(new Set(arr));
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort6(arr));    // 1, 5, 9, null, undefined

利用 ES6 中的 Set 集合里元素唯一的特性,先将数组转换为集合,这样里面的元素就是唯一的了,再用 Array.from 方法将集合转回数组返回,是不是很方便有木有?附上 Array.from 方法的官方介绍: 从一个类似数组或可迭代对象中创建一个新的数组实例.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容

  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 2,699评论 0 10
  • 父母的性格,想法,举止,父母的关系和家庭氛围都会影响到孩子,真正的爱和教育不是牺牲一方成就另一方,而是双方共同成长。
    毛攀阅读 185评论 0 0
  • 记忆使得普通的一天特别, 对我来说有人的祝福即是节日。 想起她找借口送我礼物的蠢样,可惜现在已经再也看不见了。 我...
    遐思入梦阅读 170评论 1 3
  • 说实话,每个人对于爱情可能感触各不相同,可能思想各有差异。我,在经历了之后不懂的如何去排解,去释放经历过的曾...
    半斤八两六毛六阅读 501评论 0 0
  • 前几天,有一个关系很好的高中同学,打来了电话给我诉苦。她是今年高考的落榜生,万念俱灰的她再三考虑后决定复读,记得高...
    弈澄阅读 499评论 0 1