Łukasz K
Łukasz K

Reputation: 55

Add numbers in Array using recursion and disregarding any other data type

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

Upvotes: 1

Views: 81

Answers (3)

user4639281
user4639281

Reputation:

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

Upvotes: 0

dana
dana

Reputation: 18135

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)

Upvotes: 2

Tschallacka
Tschallacka

Reputation: 28722

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 .

Upvotes: 0

Related Questions