使用 `for` 与 `slice` 的数组展平递归中的空值:为什么这两个函数的 returns 不同?

Null value in array-flattening recursion using `for` vs `slice`: why are the returns of these two functions different?

下面我提供了两个代码片段,在我看来,它们应该做同样的事情。在第一个片段中,我得到一个“空”值。我想这是因为当我在 [] 上调用 steamrollArray(arr[0]) 时,null 值作为 arr 传递给函数,将空值推入累加器。

我不知道,但我希望能得到一些帮助,避免这个特殊问题的优雅方法是什么?

我希望两个函数在给定相同输入时给出相同的输出。

作为辅助点:我很想知道是否有人可以向我指出一种将这两种方法相互比较的方法 - 这是我一无所知的东西,除了它是“一个事情”,这对我来说通常会有所帮助,以了解如何做这样的事情,特别是如何解决这个问题。

作为另一个辅助点:是否有一个交互式 javascript 解释器,就像你可以获得一个交互式 python 解释器一样(你可以在命令行中玩/测试东西)?

版本 1:“自然”递归 - returns [1,null,2,3]

function steamrollArray(arr) {
  // I'm a steamroller, baby
  //recursive (is an array)
  var accum = [];
  if (Array.isArray(arr)) {
    accum = accum.concat(steamrollArray(arr[0]));
    if (arr.length > 1) {
      accum = accum.concat(steamrollArray(arr.slice(1)));
    }
  } else {
    accum.push(arr);
  }
  return accum;
}

console.log(
  steamrollArray([1, [], [3, [[4]]]])
);

版本 2:for 循环递归 - returns [1,2,3]

function steamrollArray(arr) {
  // I'm a steamroller, baby
  //recursive (is an array)
  var accum = [];
  for (var i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      accum = accum.concat(steamrollArray(arr[i]));
    } else {
      accum.push(arr[i]);
    }
  }
  return accum;
}

console.log(
  steamrollArray([1, [], [3, [[4]]]])
);

版本 1 中,您在推送 arr[0] 时没有检查 arr[0] 中是否有元素。因此,在传递空数组 [] 的第二次调用 steamrollArray 时,arr[0] 将是未定义的:

var arr = [];

console.log(arr[0]);

为什么 版本 2 没有发生这种情况?这是因为您有一个 for 循环来包装 push 调用 (for(var i = 0; i < arr.length...)。所以当传递空数组时,for 循环永远不会进入。因为 0 < 0false.

您可以通过将 push 调用包装在 if 语句中来修复 版本 1:(推送将在 steamrollArray 被调用时发生参数 arr[0])

if(arr.length) // if length is not 0
    accum = accum.concat(steamrollArray(arr[0]));

辅助 2:NodeJs 是一个很棒的 javascript 运行时。它带有一个命令行界面。试试吧!