1

Forgive me if this is to basic or have been asked already, but I'm stuck at this problem and I feel like it must be something simple I'm not seeing.

I want to add all numbers in the array using recursion(done!) and I'm missing a statement to ignore all other types of values. For example:

var arr = [1,'a','b',2,[1],'c']
sumValues(arr) // => 4 . 

function sumValues(arr){
  if(arr.length === 0){
    return 0;
  } // if the array is empty
  if(arr.length > 0){
    if(Array.isArray(arr[0])){
      return sumValues(arr[0]);
    } // if the next element is an array
    return arr.shift() + sumValues(arr);
  }
}
2
  • Your recursive call for nested arrays uses arraySum instead of sumValues. Commented Mar 14, 2017 at 15:46
  • 1
    So then you're asking how to differentiate between a string and a number? Commented Mar 14, 2017 at 15:48

3 Answers 3

2

You can use Number.isFinite(value) to determine whether a variable is a number other than NaN or Infinity.

Based on this test, check and conditionally add values to the summation.

function sumValues(arr){
	if (arr.length === 0){
		return 0;
	} // if the array is empty
	if (arr.length > 0) {
		if (Array.isArray(arr[0])){
			return sumValues(arr[0]);
		} // if the next element is an array

		// pop the first element off the array
		var value = arr.shift();
		// check its type and conditionally add it to the summation
		return (Number.isFinite(value) ? value : 0) + sumValues(arr);
	}
}

var arr = [1,'a','b',2,[1],'c']
console.log(sumValues(arr)); // 4

arr = [1,'3','b',2,[1,[4,3]],'c'];
console.log(sumValues(arr)); // 11 (because '3' is ignored)

Sign up to request clarification or add additional context in comments.

10 Comments

This doesn't account for NaN. Use Number(value) === value to check if it is a Number instead.
Thanks for the tip!
it breaks on string numbers. [1,'3','b',2,[1,[4,3]],'c'];
Should '3' be considered a number? My take is no, but only the OP can answer for sure. I've updated my answer slightly.
All good suggestions :) I switched to Number.isFinite but left things like that since the question was really about determining whether a value was a number.
|
0

You can use isNaN() to test if something is Not a Number. By using the boolean inversion operator ! you can test if it's a number: !isNaN(variable)

Basically it says: if variable is Not Not A Number
A double negative is a positive, so it becomes: if variable Is a Number

function sumValues(arr){
  if(Array.isArray(arr)) {
     if(arr.length > 0) {
       // Get the first value and remove it from the array.
       var first = arr.shift();
       
       // Test if it's numeric.
       if(!isNaN(first)) {
          // If it is, parse the value, add the rest resulting array values.
          return parseInt(first) + parseInt(sumValues(arr));
       }
       // if the first item is an array, we need to iterate that one too.
       if(Array.isArray(first)) {
          return parseInt(sumValues(first)) + parseInt(sumValues(arr));
       }
       // It isn't a number, just continue with what's left of the array.
       return parseInt(sumValues(arr));
     }
     // The array is empty, return 0.
     return 0;
  }
  // It isn't an array
  else {
    // Is it an number?
    if(!isNaN(arr)) {
       // return the number
       return parseInt(arr);
    }
    // return 0, it's a dead end.
    return 0;
  }
}
var arr = [1,'a','b',2,[1],'c'];
console.log(sumValues(arr)) // => 4 .

arr = [1,'3','b',2,[1,[4,3]],'c'];
console.log(sumValues(arr)) // => 14 .

arr = 'foobar';
console.log(sumValues(arr)) // => 0 .

arr = '10';
console.log(sumValues(arr)) // => 10 .

arr = ['foobar',10,'20',[10,20,'foobar']];
console.log(sumValues(arr)) // => 60 .

Comments

0

You're squashing an array, there is no need to create your own reduction function. Use Array#reduce to squash the array. Upon each iteration, check if the current element is a number; if it is, add it to the accumulator; if not, move on.

To make it recursive (as shown in the example below) check if the current element is an array; if it is, add the result of calling the function on the element to the accumulator.

const input = [1,'a','b',2,[1],'c'];

const sumValues = i => 
  i.reduce((m, e) => m + (e instanceof Array ? sumValues(e) : (isNaN(e) ? 0 : e)), 0);

console.log(sumValues(input));

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.