JavaScript数组去重的方法总结【12种方法,号称史上最全】


Posted in Javascript onFebruary 28, 2019

本文实例总结了JavaScript数组去重的方法。分享给大家供大家参考,具体如下:

数组去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码。如果是被提问到,数组去重的方法有哪些?你能答出其中的10种,面试官很有可能对你刮目相看。

在真实的项目中碰到的数组去重,一般都是后台去处理,很少让前端处理数组去重。虽然日常项目用到的概率比较低,但还是需要了解一下,以防面试的时候可能回被问到。

注:写的匆忙,加上这几天有点忙,还没有非常认真核对过,不过思路是没有问题,可能一些小细节出错而已。

数组去重的方法

一、利用ES6 Set去重(ES6中最常用)

function unique (arr) {
 return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
 //[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。

二、利用for嵌套for,然后splice去重(ES5中最常用)

function unique(arr){
    for(var i=0; i<arr.length; i++){
      for(var j=i+1; j<arr.length; j++){
        if(arr[i]==arr[j]){     //第一个等同于第二个,splice方法删除第二个
          arr.splice(j,1);
          j--;
        }
      }
    }
return arr;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}]   //NaN和{}没有去重,两个null直接消失了

双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。

想快速学习更多常用的ES6语法,可以看我之前的文章《学习ES6笔记──工作中常用到的ES6语法》。

三、利用indexOf去重

function unique(arr) {
  if (!Array.isArray(arr)) {
    console.log('type error!')
    return
  }
  var array = [];
  for (var i = 0; i < arr.length; i++) {
    if (array .indexOf(arr[i]) === -1) {
      array .push(arr[i])
    }
  }
  return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}] //NaN、{}没有去重

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

四、利用sort()

function unique(arr) {
  if (!Array.isArray(arr)) {
    console.log('type error!')
    return;
  }
  arr = arr.sort()
  var arrry= [arr[0]];
  for (var i = 1; i < arr.length; i++) {
    if (arr[i] !== arr[i-1]) {
      arrry.push(arr[i]);
    }
  }
  return arrry;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
// [0, 1, 15, "NaN", NaN, NaN, {…}, {…}, "a", false, null, true, "true", undefined]   //NaN、{}没有去重

利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。

五、利用对象的属性不能相同的特点进行去重(这种数组去重的方法有问题,不建议用,有待改进)

function unique(arr) {
  if (!Array.isArray(arr)) {
    console.log('type error!')
    return
  }
  var arrry= [];
   var obj = {};
  for (var i = 0; i < arr.length; i++) {
    if (!obj[arr[i]]) {
      arrry.push(arr[i])
      obj[arr[i]] = 1
    } else {
      obj[arr[i]]++
    }
  }
  return arrry;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", 15, false, undefined, null, NaN, 0, "a", {…}]  //两个true直接去掉了,NaN和{}去重

六、利用includes

function unique(arr) {
  if (!Array.isArray(arr)) {
    console.log('type error!')
    return
  }
  var array =[];
  for(var i = 0; i < arr.length; i++) {
      if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
          array.push(arr[i]);
       }
  }
  return array
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]   //{}没有去重

七、利用hasOwnProperty

function unique(arr) {
  var obj = {};
  return arr.filter(function(item, index, arr){
    return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
  })
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}]  //所有的都去重了

利用hasOwnProperty 判断是否存在对象属性

八、利用filter

function unique(arr) {
 return arr.filter(function(item, index, arr) {
  //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
  return arr.indexOf(item, 0) === index;
 });
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]

九、利用递归去重

function unique(arr) {
    var array= arr;
    var len = array.length;
  array.sort(function(a,b){  //排序后更加方便去重
    return a - b;
  })
  function loop(index){
    if(index >= 1){
      if(array[index] === array[index-1]){
        array.splice(index,1);
      }
      loop(index - 1);  //递归loop,然后数组去重
    }
  }
  loop(len-1);
  return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]

十、利用Map数据结构去重

function arrayNonRepeatfy(arr) {
 let map = new Map();
 let array = new Array(); // 数组用于返回结果
 for (let i = 0; i < arr.length; i++) {
  if(map .has(arr[i])) { // 如果有该key值
   map .set(arr[i], true);
  } else {
   map .set(arr[i], false);  // 如果没有该key值
   array .push(arr[i]);
  }
 }
 return array ;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, "NaN", 0, "a", {…}, undefined]

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

十一、利用reduce+includes

function unique(arr){
  return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr));
// [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

十二、[...new Set(arr)]

[...new Set(arr)]
//代码就是这么少----(其实,严格来说并不算是一种,相对于第一种方法来说只是简化了代码)

PS:有些文章提到了foreach+indexOf数组去重的方法,个人觉得都是大同小异,所以没有写上去。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

Javascript 相关文章推荐
jquery 防止表单重复提交代码
Jan 21 Javascript
jQuery 一个图片切换的插件
Oct 09 Javascript
JS动态添加option和删除option(附实例代码)
Apr 01 Javascript
javascript字符串函数汇总
Dec 06 Javascript
谈一谈bootstrap响应式布局
May 23 Javascript
分析javascript中9 个常见错误阻碍你进步
Sep 18 Javascript
微信小程序使用modal组件弹出对话框功能示例
Nov 29 Javascript
浅谈React前后端同构防止重复渲染
Jan 05 Javascript
浅谈PDF.js使用心得
Jun 07 Javascript
微信小程序scroll-view实现滚动穿透和阻止滚动的方法
Aug 20 Javascript
微信小程序点击生成朋友圈分享图(遇到的坑)
Jun 17 Javascript
JavaScript原型链中函数和对象的理解
Jun 16 Javascript
vue-cli3+typescript初体验小结
Feb 28 #Javascript
详解超简单的react服务器渲染(ssr)入坑指南
Feb 28 #Javascript
JS浅拷贝和深拷贝原理与实现方法分析
Feb 28 #Javascript
微信小程序搜索功能(附:小程序前端+PHP后端)
Feb 28 #Javascript
详解写好JS条件语句的5条守则
Feb 28 #Javascript
JS判断两个数组或对象是否相同的方法示例
Feb 28 #Javascript
jQuery.parseJSON()函数详解
Feb 28 #jQuery
You might like
不用iconv库的gb2312与utf-8的互换函数
2006/10/09 PHP
六酷社区论坛HOME页清新格调免费版 下载
2007/03/07 PHP
php 特殊字符处理函数
2008/09/05 PHP
session在PHP大型web应用中的使用
2011/06/25 PHP
深入file_get_contents函数抓取内容失败的原因分析
2013/06/25 PHP
PHP小教程之实现链表
2014/06/09 PHP
ThinkPHP添加更新标签的方法
2014/12/05 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
2016/09/22 PHP
PHP数组相加操作及与array_merge的区别浅析
2016/11/26 PHP
php 7新特性之类型申明详解
2017/06/06 PHP
PHP convert_uudecode()函数讲解
2019/02/14 PHP
Javascript isArray 数组类型检测函数
2009/10/08 Javascript
jquer之ajaxQueue简单实现代码
2011/09/15 Javascript
让AJAX不依赖后端接口实现方案
2012/12/03 Javascript
原生javascript图片自动或手动切换示例附演示源码
2013/09/04 Javascript
指定区域的图片自动按比例缩小的js代码(防止页面被图片撑破)
2014/02/21 Javascript
详解JavaScript逻辑Not运算符
2015/12/04 Javascript
JS制作图形验证码实现代码
2020/10/19 Javascript
JavaScript指定断点操作实例教程
2018/09/18 Javascript
JavaScript数组类型Array相关的属性与方法详解
2020/09/08 Javascript
解决vue elementUI 使用el-select 时 change事件的触发问题
2020/11/17 Vue.js
Python基本数据类型详细介绍
2014/03/11 Python
python操作列表的函数使用代码详解
2017/12/28 Python
Django实战之用户认证(初始配置)
2018/07/16 Python
python3 面向对象__类的内置属性与方法的实例代码
2018/11/09 Python
Python编程在flask中模拟进行Restful的CRUD操作
2018/12/28 Python
python2 中 unicode 和 str 之间的转换及与python3 str 的区别
2019/07/25 Python
Python closure闭包解释及其注意点详解
2019/08/28 Python
python正则过滤字母、中文、数字及特殊字符方法详解
2020/02/11 Python
Python实现动态循环输出文字功能
2020/05/07 Python
python zip()函数的使用示例
2020/09/23 Python
2021年值得向Python开发者推荐的VS Code扩展插件
2021/01/25 Python
求职信范文怎么写
2015/03/19 职场文书
雷锋的故事观后感
2015/06/10 职场文书
Python实现简单的猜单词
2021/06/15 Python
mysql的数据压缩性能对比详情
2021/11/07 MySQL