思路:
首先.先从简单的二维转一维,比如将[1,[2,3]]转成[1,2,3],利用面向过程的思维编码如下
// 二维转一维
function flatten(arr){
var result=[];
for(var i=0,len=arr.length;i<len;i++){
if(typeof arr[i]==='object'){// 数组元素是数组
for(var j=0;j<arr[i].length;j++){
result.push(arr[i][j]);
}
}else{// 数组元素不是数组
result.push(arr[i]);
}
}
return result;
}
然后进一步思考,如果是多维数组嵌套,比如[1,[2,[3,4]],5],上面的方法就不适用了,就可以利用递归来实现多维数组的转换,主要用到arguments.callee方法.当时想着就写了下面的代码:
// 错误:result is not defined
function transfer(arr){
for(var i=0,len=arr.length;i<len;i++){
if(typeof arr[i]==='object'){// 数组元素是数组
arguments.callee(arr[i]);
}else{// 数组元素不是数组
result.push(arr[i]);
}
}
}
function flatten(arr){
var result=[];
transfer(arr);
return result;
}
var a=[1,[2,[3,4]],5];
console.log(flatten(a));
执行上面的代码在执行到result.push(arr[i]);时会报错result is not defined。主要原因是
函数的执行依赖与变量作用域,这个作用域在函数定义的时候决定的,而不是在调用的时候决定的。由于result是flatten函数的局部变量,而transfer函数又是在全局定义的,当然不能访问flatten函数的局部变量。
然后继续改进,将transfer的定义放进flatten,但函数里面的代码要调用才能执行,于是让transfer自我执行,代码如下:
// 递归实现多维数组转一维
function flatten(arr){
// 定义一个数组
// 在每次调用这个函数的时候初始化为空数组
var result=[];
// 用闭包将下面的代码与result隔离
// 使得arguments.callee指闭包而不是flatten函数
(function(obj){
for(var i=0,len=obj.length;i<len;i++){
if(typeof obj[i]==='object'){
arguments.callee(obj[i]);
}else{
result.push(obj[i]);
}
}
})(arr);// 注意:一定要把arr传进闭包
return result;
}
// 测试
var a=[1,[2,[3,4]],5];
var b=[1,[2,[3,[4,5],6],7],8];
console.log(flatten(a));
console.log(flatten(b));
总结:某些功能或项目不是一开始就能完全设计好的,许多时候需要在做的过程中遇到了问题在一步一步改进的。