为什么这个常见的JavaScript方法来深度扁平化数组不适用于所有情况?

9 浏览
0 Comments

为什么这个常见的JavaScript方法来深度扁平化数组不适用于所有情况?

我遇到了这个有趣的代码挑战:“创建一个函数,它接受一个数组并返回数组中所有项的总和。”我的解决方案是:

function sumArray(arr) {
    var merged = [].concat.apply([], arr);
    var sum = 0;
    merged.forEach(function(item) {
        sum = sum + item;
    });
    return sum;
}

问题是上面的解决方案对于sumArray([1, [2, [1]], 3]), 7失败了,因为扁平化方法不够深入。具体来说,在上述情况下,console.log(merged)[1, 2, [1], 3];

什么样的扁平化方法能够深入到必要的程度?

0
0 Comments

为什么这种常见的JavaScript方法无法在所有情况下完美地将数组深度展开?

在JavaScript中,我们经常需要对嵌套数组进行展开操作,以便更方便地处理和使用数据。通常,我们会使用Array#flat()方法来完成这个任务。这个方法接受一个可选的depth参数,用于指定展开的深度。如果depth参数未提供,则默认为1,表示只展开一层。但是,有时候我们需要展开的深度是无限的,或者我们已经知道了具体的深度。下面是一个使用Array#flat()方法展开数组并计算所有元素和的例子:

function sumArray(arr) {
   return arr.flat(Infinity).reduce((a,b) => a+b)
}
console.log(sumArray([1, [2, [1]], 3]))

在上面的例子中,我们希望展开的深度是无限的,因此我们传递了Infinity作为depth参数。然后,我们使用reduce()方法计算展开后的数组中所有元素的和。在这个例子中,我们期望的结果是7,即1+2+1+3。

然而,尽管Array#flat()方法在大多数现代浏览器中都能正常工作,但它并不是在所有情况下都能完美地展开数组。这是因为该方法在不同的JavaScript引擎中的实现方式可能会有所不同,特别是在一些较旧的浏览器中。因此,我们不能保证在所有浏览器和环境中都能正确地使用Array#flat()方法。

为了解决这个问题,我们可以使用其他方法来展开数组,而不依赖于Array#flat()方法。一种常见的解决方法是使用递归。递归是一种通过调用自身来解决问题的方法。我们可以编写一个递归函数来展开数组,如下所示:

function flattenArray(arr) {
   let flattened = [];
   arr.forEach(item => {
      if (Array.isArray(item)) {
         flattened = flattened.concat(flattenArray(item));
      } else {
         flattened.push(item);
      }
   });
   return flattened;
}
function sumArray(arr) {
   return flattenArray(arr).reduce((a,b) => a+b);
}
console.log(sumArray([1, [2, [1]], 3]));

在上面的代码中,我们首先定义了一个名为flattenArray()的递归函数,用于展开数组。该函数遍历数组中的每个元素,如果元素是一个数组,则递归地调用flattenArray()函数将其展开,并使用concat()方法将展开后的结果与已展开的数组合并;如果元素不是数组,则直接将其添加到已展开的数组中。

接下来,我们定义了一个名为sumArray()的函数,用于计算展开后的数组中所有元素的和。该函数首先调用flattenArray()函数将数组展开,然后使用reduce()方法计算所有元素的和。

最后,我们调用sumArray()函数并传递一个嵌套数组作为参数。在这个例子中,我们期望的结果仍然是7,即1+2+1+3。

通过使用递归来展开数组,我们可以在各种JavaScript环境中保证代码的兼容性,并正确地实现数组展开的功能。这种方法可能会稍微复杂一些,但它是一种可靠的解决方案,可以在不同的浏览器和环境中使用。无论是现代浏览器还是较旧的浏览器,都可以使用这种方法来展开数组并处理数据。

0