0

I'm currently working on a javascript exercise from http://toys.usvsth3m.com/javascript-under-pressure/ and my code is not working on nested arrays...I'm trying to use recursion to solve the problem, but it only seems to be adding the first element in a nested array situation...I come from a Ruby background, so javascript is a little unfamiliar to me.

If anyone could point out what I'm doing wrong, I'd appreciate it!

Thanks, Smitty

function arraySum(i) {

// i will be an array, containing integers and/or arrays like itself.
// Sum all the integers you find, anywhere in the nest of arrays.
var sum = 0;
sum = sumit(i);

return sum;
}

function sumit(i) {
var sum = 0;
for (a=0; a<i.length; a++)
{
    if (typeof(i[a]) == 'array')
    {
        sumit(i[a]);
    }
    else
    {
    sum += parseInt(i[a]);
    }
}
return sum; 
}
Smittles2003
  • 65
  • 1
  • 7

4 Answers4

0

You are not using the value of your recursive call. Try:

if (typeof(i[a]) === 'object')
{
    sum += sumit(i[a]);
}
tlrobrn
  • 11
  • 2
0

Let's take a look at your code.

  • initialise a sum variable to 0
  • Call your "helper" function on the input array, and assign its return value to sum
    • Your "helper" function initialises another variable that happens to also be called sum to zero - however it is critical to note that it is not the same variable. For clarity, I will refer to it as sum2.
    • For each item in the array...
      • If it is of type array, call the helper function on this array, but do nothing with its return value - ERROR: Arrays return their type as "object".
      • Otherwise, cast it to an integer and add it to sum2
    • Return sum2
  • Return sum

Looking at this code, there's no reason why it shouldn't work for arrays of integers. However, for subarrays, you are completely discarding the result... if you were identifying it as an array, which you are not. Instead it is also cast. Also, there's no point in having a separate function since all you're doing in your "main" function is calling it and returning its return value.

Try something like this:

function sum(arr) {
    function recurse(total,curr) {
        if( curr.constructor === Array) return total+sum(curr);
        return total+parseInt(curr,10);
    }
    if( arr.reduce) return arr.reduce(recurse,0);
    // fallback for older browsers that don't support "reduce"
    for( var i=0, l=arr.length, total=0; i<l; i++) total = recurse(total,curr);
    return total;
}

Alternative solution, untested in older IE, but should be fine assuming a reasonbly up-to-date browser:

function sum(arr) {
    arr = arr.concat.apply([],arr); // flatten the array
    for( var i=0, l=arr.length, total=0; i<l; i++) total += parseInt(arr[i],10);
    return total;
}
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
0

There are three things that are wrong.

Here is the fix with explanation in comments:

function sumit(i) {
var sum = 0;
//You need to declare a, or else it puts it in the global scope.
var a;
for (a=0; a<i.length; a++) {  //as a stylistic point, don't put { on a new line.
    //check for array by seeing if it has a length property
    if (i[a].length !== undefined) {
        //add to sum
        sum+= sumit(i[a]);
    }
    else {
        sum += parseInt(i[a]);
    }
}
return sum; 
}

First, when you use for(a = 0; . . . the declaration is in global scope.

Second, checking for typeof on array won't always work, but all arrays will have a .length

Third, as tlrobrn pointed out, you need to continue to add to 'sum'.

NOTE: I tested this solution in node with these calls

var ar = [1,1,[1,1,1,1,1],1,1,1];
console.log(sumit(ar));  //should print  10

Regarding checking for arrays: Check if object is array?

Community
  • 1
  • 1
0

my code was shorter in my test, check it out

function arraySum(i) {

var sum = 0 ; 

for ( var a in i ) {
    if ( typeof i[a] === 'object' ) { // if it is an array or object, typeof will return 'object'
        return sum + arraySum ( i[a] ) ; // recursive call
    } else if ( typeof i[a] === 'number' ) { // if it is a number, just sum it 
        sum = sum + i[a]
    }
}

return sum;

}

Hugo Ferreira
  • 184
  • 13