Reputation: 824
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!
Upvotes: 2
Views: 2294
Reputation: 7315
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):
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?
Upvotes: 6
Reputation: 48415
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]));
Upvotes: 0