Javascript中数组去重与拍平的方法示例


Posted in Javascript onFebruary 03, 2017

数组的判断

在说如何进行数组的去重和拍平之前,先说一下怎么判断数组,因为要进行数组的处理当然要先判断下传过来的数据是不是数组。

首先我们都知道js的数据类型只有5种,分别是Undefined、Null、Boolean、Number和String,数组只是一个对象,用typeof([])返回的结果知识一个Object的字符串,因此我们需要通过其他手段来判断它,这里就说两种方法。

第一种用instenceof方法

instanceof是ES5提供的一个方法,它可以用来判断实例是否是某个类的实例,例如:

[] instenceof Array
//返回结果是true

这种方法的不好之处就是兼容性不好,对于一些低版本浏览器不支持ES5的就要懵逼了。

第二种方法是通过原型链的方式来判断

了解js的话都应该懂得js这个语言的特点就是原型链式的,所有的对象都继承自Object.prototype,而prototype上又有toString()方法,这个toString()方法是干什么用的呢?就是以字符串的形式返回当前对象的值。第一次看可能这句话可能不大明白,举个例吧:

var num = 123;
num.toString(); //返回结果为"123"

有没有看明白一点?就是返回num这个对象值的字符串形式,也就是”123”。好了,这跟判断数组有什么关系?想一下所有的对象都继承自Object.prototype,数组也是啊,如果把一个数组送到Object.prototype里作为一个“值”,在调用toString()方法,那它应该显示出这个对象的名字才对啊,这就是判断的原理,代码如下:

Object.prototype.toString.call([]); //结果是"[object Array]"

像jQuery这样的脚本库的isArray()用的就是这个方法。

数组拍平

说完判直奔主题,先是数组拍平,什么是数组拍平呢?就是把[1,[2,[3,4],5]]铺成[1,2,3,4,5]。关于数组拍平我有两种思路,第二种比较奇葩,留点悬念吧哈哈。

第一种是常规思路

对数组进行遍历,如果数组里面套着数组就继续遍历里面的,直到把每个元素都遍历完,然后一边遍历一边塞入新的数组变量里,这样就完成拍平了,具体代码如下:

panelArr = function(arr){
 var newArr = [];
 var isArray = function(obj) {
  return Object.prototype.toString.call(obj) === '[object Array]';
 };
 var dealArr = function(arr){
  for (var i = 0;i<arr.length;i++){
   isArray(arr[i]) ? dealArr(arr[i]) : newArr.push(arr[i]);
  }
 };
 dealArr(arr);
 return newArr;
};
console.log(panelArr([1,[2,3]])); //[1,2,3]

当然这个方法也可以写在Array.prototype里,使用起来更方便。这个方法有个问题就是内存占用上,因为采用递归如果数据量大了会占用大量大量内存。

第二种奇葩思路

第二种思路就是不把数组来看,也不遍历了直接拍平。听起来略奇怪,怎么能不遍历就拍平?就是使用join()方法,将数组转换成字符串,然后正则去掉符号最后合并,这个方法在使用注意不能join("") ,因为如果这样分割的话,13是1和3还是13?不好区分,代码如下:

var arr = [1,2,[33,43],20,19];
arr.join(".").replace(/,/g,".").split("."); //["1", "2", "33", "43", "20", "19"]

注意:这个方法会转换数据类型成字符串。

数组去重

下面是数组去重,举例来说就是[1,2,3,3,4,5,5,5,6]变成[1,2,3,4,5,6]。这个实现的核心就是去重这里,如果能够快速判断元素是否重复就是关键。

还是两种思路

第一种遍历的思路

就是准备一个新的数组变量,塞入前每次对这个变量进行遍历看看是否有重复的,如果没有就塞入,最后生成的新数组就是去重后的数组了。示例代码如下:

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

第二种使用哈希判断

上面那个时间复杂度为O(n^2)的方法并不是什么好方法,它的瓶颈就是判断是否重复这里,所以我们换成一个更高效的检索是否重复的方法,这个方法就是哈希,为什么哈希检索最快?翻翻数据结构吧,这里就不在赘述了。

这个方法的思路就是在原始数组和去重数组之间加入一个哈希过滤,总的来看就是原数组数据交给哈希,看是否有重复,若是没有则添加进去。具体代码如下:

function uniqueArr(arr){
 var newArr = [],
 hashFilter = {};
 for(var i = 0;i<arr.length;i++){
 if(!hashFilter[arr[i]]){
 //若不存在将此属性对应的值改为true,并塞入去重数组中
 hashFilter[arr[i]] = true;
 newArr.push(arr[i]);
 }
 }
 return newArr;
}

我青睐第二种,因为在判断是否重复这里真的很快,可以说是秒出。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
Seajs的学习笔记
Mar 04 Javascript
JavaScript弹出窗口方法汇总
Aug 12 Javascript
JavaScript和CSS交互的方法汇总
Dec 02 Javascript
javascript html实现网页版日历代码
Mar 08 Javascript
在javascript中使用com组件的简单实现方法
Aug 17 Javascript
javascript容错处理代码(屏蔽js错误)
Jan 20 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
Feb 08 Javascript
JS与jQuery实现ListBox上移,下移,左移,右移操作功能示例
May 31 jQuery
在小程序中使用腾讯视频插件播放教程视频的方法
Jul 10 Javascript
jQuery操作attr、prop、val()/text()/html()、class属性
May 23 jQuery
vue 获取url里参数的两种方法小结
Nov 12 Javascript
js实现限定区域范围拖拉拽效果
Nov 20 Javascript
JavaScript中for循环的几种写法与效率总结
Feb 03 #Javascript
jquery实现刷新随机变化样式特效(tag标签样式)
Feb 03 #Javascript
漂亮实用的页面loading(加载)封装代码
Feb 03 #Javascript
理解javascript中的Function.prototype.bind的方法
Feb 03 #Javascript
JavaScript数组复制详解
Feb 02 #Javascript
常用jQuery选择器汇总
Feb 02 #Javascript
JavaScript优化以及前段开发小技巧
Feb 02 #Javascript
You might like
php学习笔记之 函数声明(二)
2011/06/09 PHP
php流量统计功能的实现代码
2012/09/29 PHP
php读取excel文件示例分享(更新修改excel)
2014/02/27 PHP
php获取远程文件内容的函数
2015/11/02 PHP
Laravel 实现数据软删除功能
2019/08/21 PHP
JS 常用校验函数
2009/03/26 Javascript
javascript学习笔记(十一) 正则表达式介绍
2012/06/20 Javascript
Raphael带文本标签可拖动的图形实现代码
2013/02/20 Javascript
异步动态加载JS并运行(示例代码)
2013/12/13 Javascript
node.js+Ajax实现获取HTTP服务器返回数据
2014/11/26 Javascript
关于webuploader插件使用过程遇到的小问题
2016/11/07 Javascript
JQuery实现图片轮播效果
2017/05/08 jQuery
微信小程序开发之map地图实现教程
2017/06/08 Javascript
Node.js上传文件功能之服务端如何获取文件上传进度
2018/02/05 Javascript
three.js实现炫酷的全景3D重力感应
2018/12/30 Javascript
微信小程序 this.triggerEvent()的具体使用
2019/12/10 Javascript
用云开发Cloudbase实现小程序多图片内容安全监测的代码详解
2020/06/07 Javascript
[01:05:56]2018DOTA2亚洲邀请赛3月29日 小组赛A组 Newbee VS VG
2018/03/30 DOTA
[01:42]DOTA2 – 虚无之灵
2019/08/25 DOTA
[47:43]完美世界DOTA2联赛PWL S3 Magama vs GXR 第二场 12.19
2020/12/24 DOTA
Python实例分享:快速查找出被挂马的文件
2014/06/08 Python
python实现的多线程端口扫描功能示例
2017/01/21 Python
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
Python实现上下班抢个顺风单脚本
2018/02/07 Python
Python生成任意范围任意精度的随机数方法
2018/04/09 Python
通过python扫描二维码/条形码并打印数据
2019/11/14 Python
python调用接口的4种方式代码实例
2019/11/19 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
2021/01/07 Python
西班牙电子产品购物网站:Electronicamente
2018/07/26 全球购物
俄罗斯三星品牌商店:Samsungstore
2020/04/05 全球购物
学生干部的自我评价分享
2014/01/18 职场文书
人力管理专业毕业生求职信
2014/02/27 职场文书
学校安全管理责任书
2014/07/23 职场文书
党的群众路线教育实践活动整改落实情况自查报告
2014/10/28 职场文书
儿子满月酒致辞
2015/07/29 职场文书
《风不能把阳光打败》读后感3篇
2020/01/06 职场文书