【问题标题】:Recursively flattening an array (why is my function not working?)递归展平数组(为什么我的函数不起作用?)
【发布时间】:2019-02-12 04:39:13
【问题描述】:

因此,我正在努力解决递归问题,最近遇到了一个问题,无论如何使用递归最容易解决。我正在尝试展平一系列不同深度的数组,我想出的功能是:

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] 但它只是按原样返回混合数组。我的想法是它需要数组,并且(假设数组不仅仅是一个数字)映射到条目。如果一个条目是单个数字,那么它应该返回那个数字,如果不是,那么它应该调用这个条目的原始函数,依此类推。希望这是一个相当基本的东西,比如语法错误(这将是相当典型的!!)

请注意;我想知道为什么我的功能不能像寻找解决方案那样工作。

谢谢(提前)

【问题讨论】:

    标签: javascript arrays recursion


    【解决方案1】:

    您不能使用普通的 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));

    【讨论】:

      【解决方案2】:

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

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

      应该做同样的事情,但使用reduce而不是map。

      【讨论】:

        【解决方案3】:

        我会把它修改成这样的。因为您实际上是将所有元素映射到相同的元素:

        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));

        【讨论】:

          猜你喜欢
          • 2023-02-07
          • 2021-10-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-21
          • 1970-01-01
          • 2020-12-07
          相关资源
          最近更新 更多