Skip to content
Advertisement

Javascript recursion function including variables

I am trying to write a function where the function returns a sub-array of the name and age key/value pairs in the objects in an array. I am to use recursion to achieve it, however I can’t find a solution that doesn’t involve keeping the num and arr2 variables outside of the function (as when they are inside they default back to zero/empty with every loop).

I have this testing out well in the console however with different arrays I am returning undefined

I am also not sure if my recursive function call is in the right place. Any tips or pointers will be very much appreciated!

   var arr =[
{name:'mike', age:22},
{name:'robert', age:12},
{name:'roger', age:44},
{name:'peter', age:28},
{name:'Ralph', age:67}
] 


var arr2 = []
var num = 0;
   

function recursive (arr) {

    if (num < arr.length ) {
        debugger
        arr2.push([arr[num].name, arr[num].age])
        num++;
        recursive(arr)
      

   
        
    } 
    
    else if (num === arr.length) {
    return arr2;
    }


}

This is my desired output:

[[ mike, 22],
[ robert, 12],
[ roger, 44],
[ peter, 28],
[ ralph, 67]]

Advertisement

Answer

To avoid global variables, you’ll need to make sure your function always returns the result. In the if block this is not happening. The recursive call is made, but even if it would return something, that return value is ignored and nothing is returned after that.

You can also avoid the num variable, by giving the recursive call a sorter array (a slice of it, excluding the value that has been processed).

Here is how you can make it work with a recursive function:

function createPairs([first, ...rest]) {
    if (first === undefined) return []; // base case
    return [[first.name, first.age], ...createPairs(rest)];
}

var arr =[{name:'mike', age:22},{name:'robert', age:12},{name:'roger', age:44},{name:'peter', age:28},{name:'Ralph', age:67}];
console.log(createPairs(arr));

Alternatively, you can pass a num index as second argument, and give it a default of 0, so that the initial call does not have to know about it (I will call it i here):

function createPairs(arr, i=0) {
    if (i >= arr.length) return []; // base case
    return [[arr[i].name, arr[i].age], ...createPairs(arr, i+1)];
}

var arr =[{name:'mike', age:22},{name:'robert', age:12},{name:'roger', age:44},{name:'peter', age:28},{name:'Ralph', age:67}];
console.log(createPairs(arr));

Another version still, avoids the creation of a new array each time the recursive call returns. We can shift the current value into the returned array. Or even better, make the index go in the backwards direction, so the array is built from left to right:

function createPairs(arr, i=arr.length-1) {
    if (i < 0) return []; // base case
    const result = createPairs(arr, i-1);
    result.push([arr[i].name, arr[i].age]);
    return result;
}

var arr =[{name:'mike', age:22},{name:'robert', age:12},{name:'roger', age:44},{name:'peter', age:28},{name:'Ralph', age:67}];
console.log(createPairs(arr));

Note that recursion is not really advised here. An iterative solution is much more suited for this problem.

function createPairs(arr) {
    return arr.map(({name, age}) => [name, age]);
}

var arr =[{name:'mike', age:22},{name:'robert', age:12},{name:'roger', age:44},{name:'peter', age:28},{name:'Ralph', age:67}];
console.log(createPairs(arr));
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement