以 var arr = [1,2,3,1]; 作为测试用例  

方法一:双循环   (时间复杂度比较高,性能一般。)

A、(1)

 1 function unique(arr) {2     var newArr = [];3     var len = arr.length;4     var isRepeat;5   6     for(var i=0; i<len; i++) {  //第一次循环7         isRepeat = false;8         for(var j=i+1; j<len; j++) {  //第二次循环9             if(arr[i] === arr[j]){
10                 isRepeat = true;
11                 break;
12             }
13         }
14         if(!isRepeat){
15             newArr.push(arr[i]);
16         }
17     }
18     return newArr;
19 } 

输出 newArr 结果:

B、(2)

 1 function unique(arr) {2     var newArr = [];3     var len = arr.length;4     for(var i=0; i<len; i++){ // 第一次循环5         for(var j=i+1; j<len; j++){ // 第二次循环6             if(arr[i] === arr[j]){7                 j = ++i;8             }9         }
10         newArr.push(arr[i]);
11     }
12     return newArr;
13 }

输出 newArr 结果:

tip:  j = ++ i; 等价于 j = j+1; i = i+1;

整体思路就是 如果是重复元素,则跳过重复元素,不对其进行 push 操作。

方法二:Array.prototype.indexOf()

A、(3)

1 function unique(arr) {
2     return arr.filter(function(item, index){ //item 表示数组中的每个元素,index 是每个元素的出现位置。
3        return arr.indexOf(item) === index; // indexOf 返回第一个索引值
4    });
5 }

输出 新 arr 结果:

tip:var new_arrary = arr.filter(callback[, thisArg]);  其中 callback 用来测试数组的每个元素的函数。调用时使用参数 element, index, array。
返回true表示保留该元素(通过测试),false则不保留。thisArg可选,执行 callback 时的用于 this 的值。

整体思路就是索引不是第一个索引,说明是重复值。

B、(4)

1 function unique(arr) {
2     var newArr = [];
3     arr.forEach(function(item){ //一次循环,item 即为数组中的每一项
4         if(newArr.indexOf(item) === -1){
5             newArr.push(item);
6         }
7     });
8     return newArr;
9 }

输出 newArr 结果:

方法三:Array.prototype.sort()

A、(5)

 1 function unique(arr) {2     var newArr = [];                  3     arr.sort();4     for(var i = 0; i < arr.length; i++){5         if( arr[i] !== arr[i+1]){6             newArr.push(arr[i]);7         }8     }9     return newArr;
10 }      

输出 newArr 结果:

tip: 整体思路就是 先进行排序,然后比较相邻元素。

B、(6)

 1 function unique(arr) {2   var newArr = [];                  3   arr.sort();4   var newArr = [arr[0]];5   for(var i = 1; i < arr.length; i++){6     if(arr[i] !== newArr[newArr.length - 1]){7      newArr.push(arr[i]);8     }9   }
10   return newArr;
11 }

输出 newArr 结果:

tip:整体思路就是 先进行排序,将原数组中的第一个元素复制给结果数组,然后检查原数组中的第 i 个元素 与 结果数组中的最后一个元素是否相同。

方法四:使用对象key来去重 (7)

 1 function unique(arr) {2     var newArr = [];3     var len = arr.length;4     var tmp = {};5     for(var i=0; i<len; i++){6         if(!tmp[arr[i]]){7             tmp[arr[i]] = 1;8             newArr.push(arr[i]);9         }
10     }
11     return newArr;
12 }

输出 newArr 结果:

tip:整体思路就是 利用了对象(tmp)的 key 不可以重复的特性来进行去重。 但是会出现如下问题需要注意:

          1、无法区分隐式类型转换成字符串后一样的值,比如 1 和 '1' 。

          2、无法处理复杂数据类型,比如对象(因为对象作为key会变成[object Object])。

          3、特殊数据,比如 '__proto__' 会挂掉,因为 tmp 对象的 __proto__ 属性无法被重写。

针对以上问题,解决办法有:

   解决问题一、三:可以为对象的 key 增加一个类型,或者将类型放到对象的value中来解决:(8)

 1 function unique(arr) {2     var newArr = [];3     var len = arr.length;4     var tmp = {};5     var tmpKey;6     for(var i=0; i<len; i++){7         tmpKey = typeof arr[i] + arr[i];8 9         console.log(tmpKey);
10
11         if(!tmp[tmpKey]){
12             tmp[tmpKey] = 1;
13             newArr.push(arr[i]);
14         }
15     }
16     return newArr;
17 }

   输出 newArr 结果:

   tip: 代码中第 9 行 console 出来的东西 如图:

          

  解决问题二:可以将对象序列化之后作为key来使用。这里为简单起见,使用JSON.stringify()进行序列化。(9)

 1 function unique(arr) {2     var newArr = [];3     var len = arr.length;4     var tmp = {};5     var tmpKey;6     for(var i=0; i<len; i++){7         tmpKey = typeof arr[i] + JSON.stringify(arr[i]);8       9         console.log(tmpKey)
10
11         if(!tmp[tmpKey]){
12             tmp[tmpKey] = 1;
13             newArr.push(arr[i]);
14         }
15     }
16     return newArr;
17 }

   输出 newArr 结果:

   tip: 代码中第 9 行 console 出来的东西 如图:

          

     看起来和上面一种方法 console 的没有区别,但是将 测试用例 换成一个 对象  var arr  = [{xiaoming:23,xiaoqing:45},{xiaoming:24,xiaoqing:45}]; 时,可以看到 console 结果如下:

          

以上都是一些比较普遍的解决办法,下面补充一下 es6 中的方法以及对于 null,NaN,undefined,{} 等类型的去重。

一、es6:

方法一: Map (10)

 1 function unique(arr) {2     var newArr = [];3     var len = arr.length;4     var tmp = new Map();5     for(var i=0; i<len; i++){6         if(!tmp.get(arr[i])){7             tmp.set(arr[i], 1);8             newArr.push(arr[i]);9         }
10     }
11     return newArr;
12 }

输出 newArr 结果:

tip: Map 是一种新的数据类型,类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。可以把它想象成key类型没有限制的对象。它的存取使用单独的get()、set()接口。

方法二:Set (11)

1 function unique(arr){
2     var set = new Set(arr);
3     return Array.from(set);
4 }

输出 newArr 结果:

tip:Set 是一种新的数据结构。它类似于数组,但是成员的值都是唯一的,没有重复的值。Array.from() 方法从类似数组或可迭代对象创建一个新的数组实例。

想要具体了解 Set 和 Map ,查看 http://wiki.jikexueyuan.com/project/es6/set-map.html

方法三:Array.prototype.includes() (12)

1 function unique(arr) {
2     var newArr = [];
3     arr.forEach(function(item){
4         if(!newArr.includes(item)){
5             newArr.push(item);
6         }
7     });
8     return newArr;
9 }

输出 newArr 结果:

二、NaN 等类型数据的去重:

使用测试用例,对上面所有算法进行验证 (以 黄色数字 为测试顺序)

1 var arr = [1,1,'1','1',0,0,'0','0',undefined,undefined,null,null,NaN,NaN,{},{},[],[],/a/,/a/]
2
3 console.log(unique(arr));

得到结果如下:

tips:

That's all ~

学习并感谢:

这么全的数组去重,你怕不怕?相关推荐

  1. 史上最全JavaScript数组去重的十种方法(推荐)

    一.前言: 我们在实际工作中,或者在面试找工作时,都会用到或者被问到一个问题,那就是"数组如何去重".是的,这个问题有很多种解决方案,看看下面的十种方式吧! 二.数组去重方式大汇总 ...

  2. 超全的数组去重12种方法

    前言 数组去重,可以说是一个比较常见的面试题,今天来盘点一下都有哪些方法可以实现数组去重. 方法1.双重for循环 这是一个最笨的方法,双重循环. var arr = [1, 2, 3,4 ,5,6, ...

  3. java数组去重_数组去重12种方案-你要的全在这

    首先我们先温习一下数组的常用的方法 pop push shift unshift slice splice sort reverse concat join indexOf lastIndexOf m ...

  4. JS----JavaScript数组去重(12种方法,史上最全)

    数组去重的方法 一.利用ES6 Set去重(ES6中最常用) Set 不包含重复元素的值的集合 Map 双列集合 键值对 与object的区别 : object中的key只能是string类型 而Ma ...

  5. 超全的12种数组去重的方法

    前言 数组去重,可以说是一个比较常见的面试题,今天来盘点一下都有哪些方法可以实现数组去重. 方法1.双重for循环 这是一个最笨的方法,双重循环. var arr = [1, 2, 3,4 ,5,6, ...

  6. 啊这,一道数组去重的算法题把东哥整不会了…

    学算法认准 labuladong 东哥带你手把手撕力扣???? 点击下方卡片即可搜索???? 想啥呢?labuladong 怎么可能被整不会?只是东哥又发现了一个有趣的套路,所以写了篇文章分享给大家~ ...

  7. 数组去重的正确编写姿势

    引言 数组去重是前端面试的一个必备题目,其具体表现内容为:怎样去掉Javascript的Array的重复项.问题简单直接,咱们也废话不多说,直入主题吧. 一般姿势 使用数组的indexOf()方法可以 ...

  8. java数组去重_再谈JavaScript数组去重

    JavaScript的数组去重是一个老生常谈的话题了.随便搜一搜就能找到非常多不同版本的解法. 细想一下,这样一个看似简单的需求,如果要做到完备,涉及的知识和需要注意的地方着实不少. 定义重复(相等) ...

  9. javascript小实例,多种方法实现数组去重问题

    废话不多说,直接拿干货! 先说说这个实例的要求:写一个方法实现数组的去重.(要求:执行方法,传递一个数组,返回去重后的新数组,原数组不变,实现过程中只能用一层循环,双层嵌套循环也可写,只做参考): 先 ...

最新文章

  1. 东八区转为0时区_踩坑记 | Flink 天级别窗口中存在的时区问题
  2. MySQL Percona PXC集群实现MySQL主从复制强一致性
  3. Nginx添加SSL的支持
  4. python如何导入自定义模块_【python】导入自定义模块
  5. H5实现拍照及相册图片上传
  6. 为转型绞尽脑汁,新东方到美国教中文!网友:卷到国外去了
  7. 通过CocoCut插件和m3u8下载器下载网页视频并转换成mp4格式
  8. 2019~2020数字货币领域发展趋势报告
  9. ​李宏毅机器学习——领域适应Domain Adaptation
  10. Spark Streaming背压机制
  11. sql计算上班总时长——以每天的第一次上下班打卡时间为准
  12. 联发科希望P40和P70救命,能如愿么?
  13. 通过公网+域名访问家里的群晖服务器
  14. 拦截图片代码 精易web浏览器_[原创]用Com HOOK实现拦截WebBrowser的alert函数调用
  15. pppoe服务器稳定性,架设pppoe服务器 实现欺骗的防御(3)
  16. POI 操作Excel的单元格样式超过64000的异常问题解决
  17. volatile c 关键字
  18. 时间的格式-用字符表示
  19. 认识计算机网络参考模型
  20. Python快速教程 - 基础篇

热门文章

  1. UA MATH564 概率论 Dirichlet分布
  2. 统计决策理论2 条件分布上
  3. UA MATH565C 随机微分方程VI 扩散过程简介
  4. Mathematica 对曲线进行拟合
  5. windbg查看SSDT表
  6. Python爬虫入门教程石家庄链家租房数据抓取
  7. Spring常用注解总结
  8. java动态代理上是否能再进行一层代理
  9. mysql table combine_Mysql系列-性能优化神器EXPLAIN使用介绍及分析
  10. jt808 位置信息方向错误_开车别大意,要掌握方向盘的正确握法,确保行车安全...