JS数组连接:递归展平后的结果

8

你好!

任务是获取一个扁平化的数组,该数组可能包括一些嵌套数组以及其他元素。对于输入[1, [2], [3, [[4]]]],输出[1, 2, 3, 4]是期望结果。FreeCodeCamp剧透警告。 自然而然地,可以想到使用递归解决,例如:

function steamrollArray(arr) {
  var result = [];
  for(var i = 0; i < arr.length; i++){
      //part of interest
      if (Array.isArray(arr[i])){
        var nestedElements = steamrollArray(arr[i]);
        for(var j = 0; j < nestedElements.length; j ++){
          result.push(nestedElements[j]);
        }
      //</part of interest>.
      } else {
        console.log("pushing: " + arr[i]);
        result.push(arr[i]);
      }
  }
  return result;
}

它会执行它的功能。样本运行的结果如下:

pushing: 1
pushing: 2
pushing: 3
pushing: 4
[1, 2, 3, 4]

问题是:当我们使用concat添加嵌套元素(这些元素应该存储递归调用的返回结果)时,出了什么问题。如果我们要将for循环中的第一个if{}块(标记为感兴趣的部分)更改为以下代码片段:
if (Array.isArray(arr[i])){
    var nestedElements = steamrollArray(arr[i]);
    result.concat(nestedElements);
} else {

我们将观察以下结果:
pushing: 1
pushing: 2
pushing: 3
pushing: 4
[1]

我的理解是将每个递归调用的结果传递给concat函数,该函数会将返回的数组添加到结果中,但由于某些原因并非如此。 类似这样的问题已经被问过了,但那些问题关注的是展开算法部分,而不是本文所述的问题。 我仍然无法看出答案,究竟是什么导致了这种差异。这很可能是我在匆忙中或因为我的有限经验而忽略掉的东西。如果是这样,请见谅。

2
Array.concat会创建一个新数组并将元素附加到该数组中,结果是全新的数组。Array.concat是不可变的,而Array.push是可变的。您可能需要将连接操作的结果再次存储到nestedElements中。 - Dhananjaya Kuppu
我在这里的教训是要仔细检查我使用的工具的规格,特别是当确切的代码行导致意外行为时。谢谢你的帮助! - shimey
3个回答

8

Array#concat 方法返回一个新的数组,其中包含调用该方法的数组与作为参数提供的一个或多个数组和/或值连接而成的结果。

concat() 方法返回一个新数组,由调用该方法的数组与作为参数传递的数组和/或值组合而成。

因此,您需要将结果赋值给一个变量:

result = result.concat(nestedElements);
// ^^^^^^ assignment

3
我对接受的答案感到困惑,因为它只能连接两个数组。针对嵌套数组,您实际上需要的是:

var flatArray = [].concat.apply([], yourNestedArray);

0

这是我的函数。

   function _recursive_array_flat( ...args )
   {
       var _ret_array = [];
       for( _arg of args )
       {
           if ( _arg instanceof Array )
           {
               if ( _arg.length > 0 ) // work with consistent elements only
               _ret_array = _ret_array.concat( _recursive_array_flat( ..._arg ) );
           }
           else _ret_array.push( _arg );
       }

       return _ret_array;
    }

    var _ret = _recursive_array_flat( [0], 1,2,3, [ 4,5,6, [ 7,8,9 ] ] );
    console.log( _ret );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接