我正在从FreeCodeCamp
开始这个挑战展平嵌套数组。你必须考虑到不同的水平 嵌套。
我正在尝试使用递归来解决它。
这是我的代码:
function steamroller(arr) {
var flatArray = [];
function flatten(obj) {
if (!Array.isArray(obj)) {
return(obj);
}
for (var i in obj) {
return flatten(obj[i]);
}
}
flatArray.push(flatten(arr));
console.log(flatArray);
}
steamroller([1, [2], [3, [[4]]]]);
此日志:
Array [ 1 ]
我可以看到问题,return语句打破for循环,所以只返回第一个值。
但是如果我遗漏退货并且只使用:
flatten(obj[i]);
我回来了:
Array [ undefined ]
我该怎么做才能解决这个问题?
答案 0 :(得分:3)
您需要将项目添加到结果数组中。
function flatten(arr){
var flat = [];
arr.forEach(function(item){
flat.push.apply(flat, Array.isArray(item) ? flatten(item) : [item]);
});
return flat;
}
答案 1 :(得分:1)
我修改了你的代码以便它可以正常工作,添加注释:
function steamroller(arr) {
var flatArray = [];
function flatten(obj) {
if (!Array.isArray(obj)) {
// We got to the innermost element. Push it to the array.
flatArray.push(obj);
return;
}
for (i = 0; i < obj.length; i++) {
flatten(obj[i]); // Do not return here.
}
}
flatten(arr);
console.log(flatArray);
}
steamroller([1, [2], [3, [[4]]]]);
答案 2 :(得分:1)
这是一种略有不同的方法:
function flat(a,f){
if (!f) var f=[];
a.forEach(function(e){
if (Array.isArray(e)) flat(e,f);
else f.push(e);
});
return f;
}
var flatArray=flat(deepArray);
该函数每次返回flattened数组,但忽略其自身内部调用中的返回值(flat(e,f)
)。相反,它会不断将每个非数组值推送到同一f
- 最初在flat(a)
外部调用中定义的数组。
使用第二个(通常是未使用的)参数,您还可以将值连接到已存在的平面数组,如
var a=[[2,4,[5,6,[7,8],[9,10]],1],3];
var fl1=flat(a);
// "2|4|5|6|7|8|9|10|1|3"
var fl2=flat(a,fl1);
// "2|4|5|6|7|8|9|10|1|3|2|4|5|6|7|8|9|10|1|3"
答案 3 :(得分:1)
完全递归解决方案,如果您不需要以保持原始数组的完整性:
function flatten (obj, memo) {
memo = (memo || []);
if (Array.isArray(obj)) {
if (obj.length) {
// flatten the first element, removing it from the original array
flatten(obj.shift(), memo);
// flatten the rest of the original array
flatten(obj, memo);
}
return memo;
}
return memo.push(obj);
}
我们首先检查obj
是否为数组。然后,如果它不是空的,将第一个元素弄平,则将其余部分弄平。如果object不是数组,则返回并推送到memo
数组,返回。
请注意,在第一行我设置memo = (memo || [])
。如果未设置memo
,这可确保我们始终在第一次调用中获得新数组。
答案 4 :(得分:0)
function steamrollArray(arr) {
let string = String(arr);
let strArr = string.split(",");
for (let i in strArr){
if (strArr[i]==""){
strArr.splice(i,1);
}
if (strArr[i]=="[object Object]"){
strArr[i] = {};
}
if (isNaN(parseInt(strArr[i],10))== false){
strArr[i] = parseInt(strArr[i]);
}
}
return strArr;
}
答案 5 :(得分:0)
因为最近这是一个新答案,也许是时候重新审视它了。
这是一个相当简单的递归过程。当问到这个问题时,ES5随处可见,ES6 / ES2015随处可见。
一个简单的ES5解决方案如下所示:
const flat = (ns) =>
ns .map (n => Array .isArray (n) ? flat (n) : n)
.reduce ((a, b) => a .concat (b), [])
但是ES6不再需要此模式,并且map-reduce(concat)
模式现在可以用Array.prototype.flatMap
编写:
const flatter = (ns) =>
ns .flatMap(n => Array .isArray (n) ? flatter (n) : n)
但是,您甚至不需要这样做,因为ES6还引入了Array.prototype.flat
,这使我们可以编写以下代码:
const flattest = (ns) =>
ns .flat (Infinity)
const flat = (ns) =>
ns .map (n => Array .isArray (n) ? flat (n) : n)
.reduce ((a, b) => a .concat (b), [])
const flatter = (ns) =>
ns .flatMap(n => Array .isArray (n) ? flatter (n) : n)
const flattest = (ns) =>
ns .flat (Infinity)
const data = [1, [2], [3, [[4]]]]
console .log (flat (data))
console .log (flatter (data))
console .log (flattest (data))