Adolf
Adolf

Reputation: 53

Recursive function issue in JS

So I need to solve this problem STRICTLY using recursion

// 2. Compute the sum of an array of integers.
// sum([1,2,3,4,5,6]); // 21

And then I'm testing this solution in PythonLive

var sum = function(array) {
  if(array.length===0){
    return array
    }
  
  return array.slice(0,array.length)+sum(array.pop())

};
sum([1,2,3,4,5,6]);

Then at step 6 it says "TypeError: array.slice is not a function"

I don't understand why if it already worked taking 6 off the array and returning the remaining array...

Can someone explain me what am I doing wrong please?

thanks! :)

Upvotes: 3

Views: 319

Answers (4)

Mulan
Mulan

Reputation: 135197

Another encoding using an explicit empty and pure expressions

const empty = x =>
  x === empty
  
const sum = ([ x = empty, ...rest ]) =>
  empty (x)
    ? 0
    : x + sum (rest)
    
console.log
  ( sum ([ 1, 2, 3, 4, 5 ]) // 15
  , sum ([])                // 0
  )

Your other question that asks how to sum a nested array was put on-hold for reasons I don't understand. You can adapt the above implementation to support input of nested arrays

const empty = x =>
  x === empty
  
const sum = ([ x = empty, ...rest ]) =>
  empty (x)
    ? 0
    
  : Array.isArray (x)
    ? sum (x) + sum (rest)
  
  : x + sum (rest)
    
console.log
  ( sum ([ 1, [ 2, [ 3, 4 ], 5 ]]) // 15
  , sum ([ 1, 2, 3, 4, 5 ])        // 15
  , sum ([[[]]])                   // 0
  , sum ([])                       // 0
  )

Upvotes: 0

Mark
Mark

Reputation: 92440

If you look at the return values you will see that you are always returning an array. This can't be right when you want a number as a final result. When array.length === 0 you can safely return 0 because that's the same of an empty array. That's your edge condition. After that you just want the sum of one element plus the rest.

You can also just return the array length when it's zero making for a very succinct solution. && shortcircuits returning the left element if it's false (like 0) otherwise the second:

var sum = (array) => array.length && array.pop() + sum(array)

console.log(sum([1,2,3,4,5,6]));

If you prefer slice you could also this, which is basically the same:

var sum = (array) => array.length && array[0] + sum(array.slice(1))

console.log(sum([1, 2, 3, 4, 5, 6]));

Upvotes: 2

Nick
Nick

Reputation: 147146

The issue with your code is that you are processing the values the wrong way around, it should be

return sum(array.slice(0,array.length-1)) + array.pop();

In fact since array.pop() removes the element, you can just do it this way around:

return array.pop() + sum(array);

You also need to return 0 when array.length===0, otherwise the sum will fail.

if (array.length===0) return 0;

However it's much simpler just do this with reduce:

let arr = [1,2,3,4,5,6];
console.log(arr.reduce((t, v) => { return t + v; }, 0));

Upvotes: 1

Jared Smith
Jared Smith

Reputation: 21926

Recursive sum function:

const sum = list => {
  if (!list.length) return 0;
  return list.pop() + sum(list);
};

Because .pop mutates the array, you don't need to use slice. For a non-destructive version (doesn't alter the original array):

const sum = ([first, ...rest]) => {
  if (first === undefined) return 0;
  return first + sum(rest);
};

Upvotes: 1

Related Questions