本文详细解析JavaScript中数组处理的三个核心问题:如何准确判断数组类型,包括typeof局限性与原型链检测法;如何实现数组拍平,对比递归遍历与字符串转换两种思路;以及如何高效去重,分析时间复杂度为O(n^2)的遍历法与基于哈希表的快速检索法。
JavaScript数组类型判断
数组类型判断
在讨论数组去重与扁平化之前,首先需要明确如何判断一个变量是否为数组。因为对数组进行操作的前提是确认传入数据的类型。
首先我们都知道js的数据类型只有5种,分别是Undefined、Null、Boolean、Number和String,数组只是一个对象,用typeof([])返回的结果知识一个Object的字符串,因此我们需要通过其他手段来判断它,这里就说两种方法。
第一种方法:使用instanceof运算符
instanceof是ES5标准提供的一种运算符,用于判断实例是否属于某个类。例如:
[] instenceof Array
//返回结果是true
该方法的缺点在于兼容性较差,对于不支持ES5的旧版浏览器无法使用。
第二种方法:基于原型链的检测
熟悉JavaScript的人都知道,该语言基于原型链机制,所有对象都继承自Object.prototype,而toString()方法存在于原型上。toString()方法的作用是返回当前对象值的字符串形式。初看可能难以理解,举例说明:
var num = 123;
num.toString(); //返回结果为"123"
上述代码返回数字对象值的字符串形式,即"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,导致结果错误。具体代码如下:
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中数组判断、去重与扁平化的相关实现方法,希望对学习或工作有所帮助。如有疑问,欢迎留言交流。