2

I am going through Javascript from the beginning. No shortcuts, no framework, nothing. Just plain Javascript. And just for the fun of it, I am doing every exercise. Now, when I get to this one question:

Write a function arrayToList that builds up a data structure like

var list = {
  value: 1,
  rest: {
    value: 2,
    rest: {
      value: 3,
      rest: null
    }
  }
};

My code has to be able to fulfill the following:

console.log(arrayToList([10, 20])); 
// → {value: 10, rest: {value: 20, rest: null}} <== expected output which I am sure you know

I tried to do this recursively as the later question wants us to do it recursively (recursion is one of my weakest points!). But, I got the following code up:

var list = 
    {
      value: 0,
      rest: null
    }

function arrayToList(array)
{   
  list.value = array.shift();

    if(array.length!=0)
    {
      list.rest = arrayToList(array);
    }
  else
  {
    list.rest = null;
    console.log(list); //this outputs to {value: 20, rest: null}
    return list;
  } 
  return list;
};

However, the output

{value: 20, rest: {value: 20, rest: {
                                      value:    20
                                      rest: {value: 20, rest: {value: 20, …}}
}}} 

The ... refers to the same block of

{value:20, rest:{value:20, rest: {...}}

Well, I did not expand to the end to see (its too long! (after about 20 times opening is still the same) IF there is an end at all).

Hoping to have someone guide me to the answer. I have spent couple of days on this already and am stuck.

Thanks a lot and have a good day all!

2 Answers 2

6

Guidance (hopefully!)

You do not need a global list variable, like you're currently using (unless you're trying to do some complex optimisation – don't worry about it for now). In fact, it looks like this global list variable is what's causing your problems. I will try to walk you through the correct way to do this from the beginning.

First, try to identify what the 'repeated' part of the output needs to looks like. In your case, the repeated part is:

{
    value: someValue,
    rest: RECURSION
}

because if you swap RECURSION for that SAME structure above, you get the exact cascading effect you need:

{
    value: someValue,
    rest: {
        value: someValue,
        rest: RECURSION
    }
}

and so on.

Once you've identified that, your function literally just needs to return that object. It is that simple. Swap someValue for that front value (i.e. the return value of arr.shift()), and swap RECURSION for a call back to your function, passing it the rest of the array. Which gives:

function arrayToList(arr) {
    var value = arr.shift();

    return {
        value: value,
        rest: arrayToList(arr) // arr has already had its front value removed, by .shift()
    };
}

The only thing left to add is an end condition, so that if there are no more values left the recursion just returns null (otherwise we'd loop forever):

Full solution

function arrayToList(arr) {
    if (arr.length === 0) {
        return null;
    }
  
    var value = arr.shift();

    return {
        value: value,
        rest: arrayToList(arr)
    };
}

console.log(arrayToList([10, 20])); // {value: 10, rest: {value: 20, rest: null}}

That's it! Does that make sense?

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

3 Comments

Yes. Very simple and straightforward code and very understandable. Thanks a lot @Shai! May I know where can I learn about recursive? I am very weak in that area.
No problem. Have you Googled javascript recursion? codecademy.com/courses/javascript-lesson-205/0/1, for example.
Well, yes I did. I even read using books. But the core concept always elude me as I still couldn't grasp it well enough to use it. Probably fear. I'll give it a try again. Thanks a gain Shai :)
0

You need to keep a list of the last item that you added, as this will be the item that you add the next one to.

Something like this:

var list = null;

function arrayToList(array) {
  var last = null;

  for (var i = 0; i < array.length; i++) {
    var item = {
      value: array[i],
      rest: null
    };
    if (last == null)
      list = item;
    else
      last.rest = item;
    last = item;
  }

  return list;
}

console.log(arrayToList([10, 20]));

1 Comment

Thanks for the answer but I required it as in recursion. But thanks nonetheless :)

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.