2

我正在尝试和解决 8m 7s 中提到的问题的朋友一起玩,对我来说它已经走了 20m。我不知道如何在 javascript 中处理无限的嵌套数组。

问题是这样的:

// i will be an array, containing integers, strings and/or arrays like itself.
// Sum all the integers you find, anywhere in the nest of arrays.

所以

arraySum([[1,2,false],'4','5']) will return 3 (passed)
arraySum([[1,2,3],4,5]) will return 15 (passed)
arraySum([[[[[[[[[1]]]]]]]], 1]) will return 2 (failed)

我写的代码是:

function arraySum(i) {

sum = 0;
tmp =0;
for (var a=0; a<i.length; a++){
    if (i[a] instanceof Array) {
        ar = i[a];
        for (var j=0; j<ar.length; j++){
            tmp +=ar[j];
        }
    }
    if (typeof i[a] == "number")
        sum += i[a];
        console.log(sum);
}
return sum + tmp;

}

如您所见,它无法处理我失败的最后一种情况,因为我无法弄清楚如何在 JS 中处理无限嵌套。

任何想法将不胜感激。也尽量在 8m 7s 之前完成它,我的伙伴完成了。

4

6 回答 6

16

在该if (i[a] instanceof Array) {部分内部,您必须使用递归来操作具有相同arraySum功能的嵌套数组,而不仅仅是使用另一个循环。尝试这个:

var arraySum = (function () {
    "use strict";

    var sumFunc, isArray;

    sumFunc = function (arr) {
        var sum, i, j, cur, toAdd;

        sum = 0;

        for (i = 0, j = arr.length; i < j; i++) {
            cur = arr[i];

            toAdd = 0;
            if (isArray(cur)) {
                toAdd = sumFunc(cur);
            } else if (typeof cur === "number") {
                toAdd = cur;
            }

            sum += toAdd;
        }

        return sum;
    };

    isArray = Array.isArray || function (obj) {
        return Object.prototype.toString.call(obj) === "[object Array]";
    };

    return sumFunc;
}());

演示:http: //jsfiddle.net/Q7JPM/1

该函数只是遍历数组中的所有项目,并返回其中找到的任何数字的总和。如果项目本身是一个数组,它会调用arraySum并传递该数组...将结果添加到总和中。如果它是一个数字,它只是将它添加到总和中。

于 2013-10-04T14:38:04.850 回答
4

你必须使用递归:

http://jsfiddle.net/HMnat/2

function arraySumRec(theArray)
{
    var sum=0;
    for (var i=0;i<theArray.length;i++)
    {
        if (theArray[i] instanceof Array)
        {
            sum=sum+arraySumRec(theArray[i]);
        }
        else
        {
            if (typeof(theArray[i])=="number")
                {
                 sum=sum+theArray[i];
                }
        }
    }
      return sum;
}

花了我 3 分 47 秒(由于错字,哈哈)。

于 2013-10-04T14:46:22.417 回答
2
function arraySum(i) {
        var l = i.length, sum = 0;
        while (l--) { 
            if (typeof i[l] !== 'number' && !(i[l] instanceof Array)) continue;
            if (i[l] instanceof Array) { sum += arraySum(i[l]); continue; }
            sum += i[l];
        }
        return sum;
}
于 2013-10-04T21:09:49.300 回答
2

Javascript Array reduce 方法非常适合解决此类问题。reduce 方法接受一个至少有两个参数的函数:累加器和数组的当前元素。在函数体中,您指定每个元素应如何影响累加器。函数的第二个参数是累加器的起始值。

function sum(x) {
  return x.reduce(function(accumulator, currentValue) {
    if (typeof currentValue === "number") {
      return accumulator + currentValue;
    } else if (currentValue instanceof Array) {
      return accumulator + sum(currentValue);
    } else {
      return accumulator;
    }
  }, 0);
}

JSFIDDLE

函数 sum 接受一个数组,reduce 方法将其缩减为单个值。在“else if”分支中,我们找到了一个嵌套数组,我们可以简单地对其调用 sum,取回一个值,并将其添加到我们的累加器中。在“else”分支中,我们还没有找到我们感兴趣的值类型,所以我们保持累加器不变。

MDN的文档通过示例很好地解释了 Array reduce。

于 2013-10-04T15:20:02.703 回答
1

使用堆栈的非递归。

        function arraySum(arr) 
        {
            var sum = 0;   

            while(arr.length != 0)
            {
               var value = arr.pop();
               if(value instanceof Array)
               {
                 for (i= 0; i< value.length; ++i) 
                   arr.push(value[i]);
               }
               else if(typeof value === "number")
                sum += value;
             }

             return sum;
        }

        var arr = [1, 2, [3, 4, [[[5]]]]];
        console.log(arraySum(arr));
于 2015-02-23T22:54:57.680 回答
0

如果我们专注于正确的部分,我们就可以避免专注于错误的部分——

function arraySum (t)
{ switch (t?.constructor)
  { case Array:
      return t.reduce((r, v) => r + arraySum(v), 0)
    case Number:
      return t
    default:
      return 0
  }
}

console.log(arraySum([[1,2,false],'4','5']))
console.log(arraySum([[1,2,3],4,5]))
console.log(arraySum([[[[[[[[[1]]]]]]]], 1]))

3
15
2

如果?.您的环境尚不支持,您可以将其换掉 -

switch (t?.constructor)
switch (t && t.constructor) // <- where ?. is unsupported

编辑:我花了 2,769 天来回答这个问题,但只用了几分钟来写:D

于 2020-11-11T14:26:56.833 回答