1

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

This is what I came up with, but still not right yet

function arraySum(arr) {
  var sum = 0;
  var sum1 = 0;

  for (var i = 0; i < arr.length; i++) {
    if (arr[i] === Math.round(arr[i])) { //check if its an integar
      sum += arr[i];
    }  
    if (arr[i] instanceof Array) {
      for (var n = 0; n < arr[i].length; n++) {
        sum1 += arr[i][n];
      }
    }
  }
  console.log(sum + sum1);
}

var sumArr = [[[[[[[[[1]]]]]]]], 1]; // => 101. SHOULD BE 2
arraySum(sumArr);
4
  • it would be simpler to flatten then sum (both one-line operations), and since addition is associative and communicative, the answer will be the same. Commented Apr 7, 2015 at 20:52
  • 3
    [[[[[[[[[1]]]]]]]], 1].toString().match(/[\d\.]+/g).map(Number).reduce(function(a,b){return a+b; }) Commented Apr 7, 2015 at 20:54
  • I could be wrong, but I feel like you might benefit from changing: 'if (arr[i] === Math.round(arr[i])) { //check if its an integer ' to 'if(arr[i] === math.round(arr[i]) && isNaN(arr[i]) === false) { //check if it's an integer and IS a number. ' Commented Apr 7, 2015 at 21:01
  • recursive means the function calls itself. Instead of attempting to sum the array (which may have further nested arrays), you should pass the array to arraySum, and add the return value to your sum. Commented Apr 7, 2015 at 21:16

7 Answers 7

6
function arraySum(arr) {
  var sum = 0;
  for (var i = 0; i < arr.length; i++) {
     if (arr[i] instanceof Array) { sum += arraySum(arr[i]);}
     if (arr[i] === Math.round(arr[i])) {sum += arr[i];}   
  }
 return sum;
}
Sign up to request clarification or add additional context in comments.

Comments

5

What about using reduce recursively?

function arrSum(arr) {
    return arr.reduce(function fn(a, b) {
        if (Array.isArray(b)) {
            return b.reduce(fn, a);
        } else if (b === Math.round(b)) {
            return a + b;
        } 

        return a;
    }, 0);
}

The reduce() method applies a function against an accumulator and each value of the array (from left-to-right) has to reduce it to a single value.

2 Comments

doesn't support ie8, but i will definitely consider using it after finding a cross-browser solution
3
function add(array){
  return(array+"").match(/-?\d+(?:\.\d+)?/g).reduce(function(a,b) {
    return +a+ +b;
  });
}

That uses regex to parse a stringified array but it should work just fine. So then there'll be an array with only the numbers. Those get parsed into a .reduce() which adds them. The best I could think of :) help from: mdn

function add(n){return JSON.stringify(n).match(/[^\D]+/g).reduce(function(n,r){return 1*n+1*r})} is what came out of http://jscompress.com

SPEED: 0.04395800351630896s Either 11% faster than other answers, or my Math's terrible

A more supported answer:

function add (array) {
    var nums = JSON.stringify(array).match(/[\d\-]+/g),
        i,
        sum = 0;
    for (i = 0; i < nums.length; i += 1) {
        sum += parseInt(nums[i], 10);
    }

    return sum;
}

9 Comments

judging by the edits, i think you mean the best i could think of ;)
@dandavis ohhh. wow, i used mdn which i found after a quick google search. Updated to show that
Since we're going with oneliners replace return parseInt(a,10) + parseInt(b,10); with return a*1 +b*1; to shorten it further..
or return +a + +b to shorten it further
@user2734550 If you going to be using this functions many times (more than ten) I would recommend a fast solution (this one) ;)
|
1

You can solve this using recursive functions, try with something like this:

function arraySum(arr) {
var sum = 0;

for (var i = 0; i < arr.length; i++) {
    if (arr[i] === Math.round(arr[i])) { 
        sum += arr[i];
    }  
    if (arr[i] instanceof Array) {
        sum += arraySum(arr[i]); //This will apply the same function to the current Array element which is an Array
    }
}
return sum; //To have the sum of the actual Array
}
    var sumArr = [[[[[[[[[1]]]]]]]], 1];

console.log(arraySum(sumArr)); //now it returns 2

2 Comments

This is good. Only, the Integer check will fail for strings eg "5" due to strict equality check.
@levi you're right, but since the instruction was to "Sum all the integers you find" I think that's not necessary.
0

Try this :

function arraySum(arr) {
    return arr.reduce(function(s, n) {
        return s + ((n instanceof Array) ? arraySum(n) : +n || 0);
    }, 0);
}

+n attempts to convert strings to integers, defaulting to zero if +n yields NaN.

http://jsfiddle.net/3z7pakfx/

2 Comments

Good one, it just fails on numerical strings, e.g '1'.
Yes, me too - so, it should work like this (convert strings to integers)?
0

Here is a solution that doesn't rely on iteration:

var arraySum = function(array) {
  if (array.length === 0) {
    return 0;
  }
  var rest = array.slice();
  var next = rest.pop();
  if (next instanceof Array) {
    return arraySum(next) + arraySum(rest);
  } else {
    return next + arraySum(rest);
  }
};

Comments

0

The sum of any value, v, and more values is -

  1. If we do not have a value, v, return the empty sum, 0
  2. By induction, we have a value, v. If the value is an array, return the sum of v plus the sum of more
  3. By induction, we have a value v that is not an array. Return the numeric value of v plus the sum of more

const sum = ([ v, ...more ]) =>
  v === undefined
    ? 0                   // 1
: Array.isArray(v)
    ? sum(v) + sum(more)  // 2
: Number(v) + sum(more)   // 3

const result =
  sum([[[[[[[[[1]]]]]]]], 1])

console.log(result)
// 2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.