最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

algorithm - Javascript unlimited nested array handling - Stack Overflow

programmeradmin1浏览0评论

I am trying to have fun with my buddy who solved the problem mentioned in 8m 7s, and for me it is already 20m gone. I can't figure out how to handle unlimited nested array in javascript.

The problem is this:

// 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.

So

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)

The code I wrote is:

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;

}

As you can see it does not handle the last situation that I failed as I can't figure out how to handle unlimited nest in JS.

Any idea will be much appreciated. Also try to finish it before 8m 7s, which my buddy finished in.

I am trying to have fun with my buddy who solved the problem mentioned in 8m 7s, and for me it is already 20m gone. I can't figure out how to handle unlimited nested array in javascript.

The problem is this:

// 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.

So

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)

The code I wrote is:

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;

}

As you can see it does not handle the last situation that I failed as I can't figure out how to handle unlimited nest in JS.

Any idea will be much appreciated. Also try to finish it before 8m 7s, which my buddy finished in.

Share Improve this question edited Jan 23, 2015 at 17:27 schesis 59.1k28 gold badges154 silver badges163 bronze badges asked Oct 4, 2013 at 14:26 mmrs151mmrs151 4,0723 gold badges35 silver badges38 bronze badges 1
  • 4 Inside of the if (i[a] instanceof Array) { part, you'll have to use recursion, not just a nested loop – Ian Commented Oct 4, 2013 at 14:28
Add a comment  | 

6 Answers 6

Reset to default 16

Inside of the if (i[a] instanceof Array) { part, you'll have to use recursion to operate on nested arrays with the same arraySum function, not just use another loop. Try this:

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

The function just loops through all items in an array, and returns the sum of any numbers found inside. If the item is an array itself, it calls arraySum and passes that array...adding the result to the sum. If it's a number, it simply adds that to the sum.

You have to use recursion:

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;
}

Took me 3 minutes 47 seconds (due to a typo, ha ha).

The Javascript Array reduce method is perfect for solving this kind of problem. The reduce method takes a function with at least two arguments: the accumulator and the current element of the array. In the body of the function, you specify how each element should affect the accumulator. The second argument to the function is the starting value of the 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

The function sum takes an array, and the reduce method reduces it to a single value. In the "else if" branch, where we find a nested array, we can simply call sum on it, get back a single value, and add that to our accumulator. In the "else" branch, we haven't found the kinds of values we're interested in so we leave the accumulator unchanged.

The documentation at MDN provides a good explanation of Array reduce with examples.

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;
}

Non-Recursive using a stack.

        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));

If we focus on the right parts, we can save ourselves the tedium from focusing on the wrong parts -

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

If ?. is not yet supported in your environment, you can swap it out -

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

Edit: it took me 2,769 days to answer the question but only a few minutes to write it :D

发布评论

评论列表(0)

  1. 暂无评论