任务说明: 对嵌套的数组进行扁平化处理。你必须考虑到不同层级的嵌套。
steamroller([[["a"]], [["b"]]]) 应该返回 ["a", "b"]
steamroller([1, [2], [3, [[4]]]]) 应该返回 [1, 2, 3, 4]
steamroller([1, [], [3, [[4]]]]) 应该返回 [1, 3, 4]
steamroller([1, {}, [3, [[4]]]]) 应该返回 [1, {}, 3, 4]
任务解析:
嵌套数组会是多级的,如果数组元素都是数字或字符串,可以直接使用Array.prototype.join()方法先转换为字符串,然后再使用String.prototype.replace(),方法去除",",最后用字符串的split()方法返回数组。代码示例如下:
function steamroller(arr) {
// I'm a steamroller, baby
var arrString=arr.join("");
arrString=arrString.replace(/[,]/g,"");
return arrString.split("");
}
然而,如果数组元素中有对象,如{},这种方法就不能正常显示,所以必须考虑其他方法。
方法(一)设置全局变量,采用递归方式
//全局变量,用于存放递归返回的结果
//如果在函数内部声明局部变量,则在每次递归过程中
//result都会刷新,把之前结果丢弃
var result=[];
function steamroller(arr) {
// I'm a steamroller, baby
for(var i=0;i<arr.length;i++){
//判断元素是不是数组,是则递归调用,不是则保存元素
if(Array.isArray(arr[i])){
steamroller(arr[i]);
}else{
result.push(arr[i]);
}
}
return result;
}
alert(steamroller([1, [], [3, [[4]]]]));
由于这种方法在freeCodeCamp里不能通过,因此不建议使用全局变量的方式,可以使用辅助函数或是其他方式。
方法(二)内部声明result,将每次递归调用结果与result[]拼接在一起
unction steamroller(arr) {
// 内部变量result[]保存递归结果
var result=[];
for(var i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
//将每次递归的结果进行拼接,就会避免上面所遇到的局部变量被清空的问题
result=result.concat(steamroller(arr[i]));
}else{
result.push(arr[i]);
}
}
return result;
方法(三) 使用辅助函数,避免全局变量的问题
//辅助函数
function helper(arr,result){
for(var i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
helper(arr[i],result);
}else{
result.push(arr[i]);
}
}
return result;
}
//调用辅助函数
function steamroller(arr) {
// I'm a steamroller, baby
var result=[];
return helper(arr,result);
}
也可写成如下方式:
function steamroller(arr) {
// I'm a steamroller, baby
var result=[];
//辅助函数
var helper=function(arr,result){
for(var i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
arguments.callee(arr[i],result);
}else{
result.push(arr[i]);
}
}
return result;
};
return helper(arr,result);
}
方法(四)使用Array.prototype.reduce()方法累加
本方法借鉴自http://www.tuicool.com/articles/vUB3MnU。个人觉得这个方法比较高大上。
具体算法如下:
function steamroller(arr) {
// I'm a steamroller, baby
//storage为累加器初始值,item为数组当前元素
var result = arr.reduce(function callee(storage, item) {
if (item instanceof Array) {
//元素是数组时,递归调用callee函数,并将上次计算结果作为初始值
item.reduce(callee, storage);
} else {
storage.push(item);
}
return storage;
}, []);//累加器初始值为空数组
return result;
}