递归展平数组(为什么我的函数不起作用?)

时间:2019-02-11 20:28:23

标签: javascript arrays recursion

因此,我试图绕过递归,最近遇到了一个问题,无论如何,使用递归最容易解决。我试图展平各种深度数组,而我想实现的功能是:

mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];

function flattenArray(array) {
	return array.map(val => {
		if (typeof val !== "number") {
			return flattenArray(val);
		} else {
			return val;
		}
	});
}

console.log(flattenArray(mixedArray));

现在,我希望它能输出[1,2,3,4,5,6,7,8,9],但它只是按原样返回mixedArray。我的想法是,它采用数组,并且(假设数组不仅仅是一个数字)通过条目进行映射。如果一个条目是单个数字,则它应该返回该数字,否则,它应该在该条目上调用原始函数,依此类推。希望这是一个相当基本的东西,例如语法错误(这很典型!)

请注意;我想知道为什么我的功能不能很好地解决问题。

(先感谢)

3 个答案:

答案 0 :(得分:5)

您不能使用普通的map方法来执行此操作,因为该方法只会返回与应用map的数组(即顶层)中相同数量的元素。

请改为使用reduce,然后确保使用必须添加的内容扩展已有的内容:

mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];

function flattenArray(array) {
    return array.reduce( (flat, val) => {
        if (typeof val !== "number") {
            return [...flat, ...flattenArray(val)];
        } else {
            return [...flat, val];
        }
    }, []);
}

console.log(flattenArray(mixedArray));

您可以使用三元运算符代替if ... else来稍微压缩代码:

mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];

const flattenArray = array =>
    array.reduce( (flat, val) => 
        [...flat, ...(Array.isArray(val) ? flattenArray(val) : [val])]
    , []);

console.log(flattenArray(mixedArray));

...,当然,我们应该提到ESNext提案Array#flat,该提案只需一个方法调用即可完成所有工作。

mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];

console.log(mixedArray.flat(Infinity));

答案 1 :(得分:2)

问题在于将数组映射到数组不会改变它,它仍然是结果数组中的一个数组:


function flattenArray(array) {
  return array.reduce((result, x) => result.concat(
    Array.isArray(x) ? flattenArray(x) : x), [])
}

应该这样做,但是使用reduce而不是map。

答案 2 :(得分:1)

我将其修改为如下所示。因为您实际上是将所有元素映射到相同的元素:

mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];

function flattenArray(array, out=[])
{
    array.forEach(val =>
    {
        if (typeof val !== "number")
            out = out.concat(flattenArray(val));
        else
            out.push(val);
    });
    
    return out;
}

console.log(flattenArray(mixedArray));