user4853
user4853

Reputation: 363

How does this recursive function end?

This is from nodeschool's functional javascript workshop. Here is the code as it appears there:

function toUpperArray(items) {
    if (!items.length) return []    // end condition
    var head = items[0]             // item to operate
    head = head.toUpperCase()       // perform action
    var tail = items.slice(1)       // next
    return [head].concat(toUpperArray(tail))    // recursive step
}

toUpperArray(['hello', 'world']) // => ['HELLO', 'WORLD']

I don't understand how the "end condition" works. I think that conditional is looking for the items.length to be 0, but then it returns an empty array? I have tried running this by having it return nothing, which returns undefined thus adds undefined to the final array, but I am not sure why returning an empty array fixes this. I would expect the final item in the final array to be an empty array.

Also, I have never seen a conditional that didn't use curly braces. Is that significant?

Upvotes: 1

Views: 209

Answers (5)

ooo
ooo

Reputation: 1627

When the items.length will be eqal to 0 (false), the function will return an empty array and will go up the recursion call stack. Here is a couple way we could have written this condition:

if(!items.length) //true
if(items.length == 0) //true
if(items.length == false) //true

For the conditions without curly braces. It does the same thing except that it only takes the current line or the next line as the "content" of your condition:

if(randomBoolean)
    console.log('this is executed');

console.log('this is always executed');

In that example if the randomBoolean variable is true the output will be:

this is executed
this is always executed

If the randomBoolean variable is false, you will see:

this is always executed

Upvotes: 1

Eskalior
Eskalior

Reputation: 252

function toUpperArray(items) {
    if (!items.length) return []    // end condition
    var head = items[0]             // item to operate
    head = head.toUpperCase()       // perform action
    var tail = items.slice(1)       // next
    return [head].concat(toUpperArray(tail))    // recursive step
}
  • Line 1: If there are no items left in the array, return an array with nothing in it.
  • Line 2: Take the first item of the given array
  • Line 3: transform it into upper-case letter
  • Line 4: create a new array without the just transformed item
  • Line 5: call the function with the remaining array, concat it with the transformed item and return.

What happens? lets take your example:

[ X, Y ] means, you have an array with array[0] = X, array[1] = Y. So you have items[0] = 'hello', items[1] = 'world'.

The first call is transforming 'hello' to 'HELLO'.

The remaining array is ['world'].

then the function gets called again and transforms it to 'WORLD'.

Then it is called again, has no items and then it returns an empty array. This means the second call can return too by concating ['WORLD'] with [].

Then the first call can return by concating ['HELLO'] with ['WORLD'] which is ['HELLO', 'WORLD'].

Upvotes: 1

Jack
Jack

Reputation: 133609

This is because of concat functions which called on Array and with an Array as argument produces an Array as result. Basically you can see it in this way:

  • the upper array of an empty array is an empty array (base case)
  • the upper array of an array with at least one element (think of it as element,[array]) is element.toUpperCase() concatenated with the trailing part of the array through the recursive call (recursive step)

Basically you have an array data = [e1, e2, ..., en] and a function f(x). You want to return [f(e1), f(e2), ..., f(en)] so you basically apply the function on the first element on the array and concatenate the result with the value returned from the same recursive function on the same array without the first element.

Upvotes: 2

Zimbabwe Elephant
Zimbabwe Elephant

Reputation: 1091

It converts all the values in the array up to UPPERCASE.

Could use for loop but they basically just call the function again for the next array value.

Upvotes: -2

rajuGT
rajuGT

Reputation: 6404

When the array is empty. i.e. items.length == 0. The below condition is short form of != 0 because 0 is a false value in javascript, not of 0 should be true.

if (!items.length) return [];

Upvotes: 2

Related Questions