Javascript无限嵌套数组处理

时间:2013-10-04 14:26:56

标签: javascript algorithm recursion nested multidimensional-array

我正试图和我的伙伴一起玩,他解决了8m 7s中提到的问题,对我而言,它已经消失了20米。我无法弄清楚如何在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之前完成它,我的好友完成了。

6 个答案:

答案 0 :(得分: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;
}());

DEMO: http://jsfiddle.net/Q7JPM/1

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

答案 1 :(得分:3)

你必须使用递归:

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秒(由于打字错误,哈哈)。

答案 2 :(得分:2)

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

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”分支中,我们没有找到我们感兴趣的值的类型,因此我们保持累加器不变。

documentation at MDN通过示例提供了对Array reduce的一个很好的解释。

答案 3 :(得分: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;
}

答案 4 :(得分: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));

答案 5 :(得分: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

编辑:我花了2769天来回答这个问题,但只花了几分钟就写出了:D