3

Having trouble with an exercise from the Eloquent Javascript book. The task is to create a list out of an array.

The list is something like this:

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

The solution on the website of the book is:

function arrayToList(array) 
{
  var list = null;
  for (var i = array.length-1; i>=0; i--) {
      list = {value: array[i], rest: list};
  }
  return list;
}

I understand how it works, but don't get why. As I would have imagined the loop would rewrite the list object, while its rest property would point to the object that contains it. Can someone explain me how and why it works?

I have also tried the solution in my browser (Firefox 33) and console.log(arrayToList([10,20])) prints out "undefined"

1 Answer 1

4

It starts at the end of the array wrapping the previous result in a new object each time, meaning the structure gets deeper and deeper.

Going though it loop by loop for array [1,2,3]

The first loop:

i = 2
array[2] is 3
list = {value: 3, rest: null}

The second:

i = 1
array[1] is 2
list = {value: 2, rest: {value: 3, rest: null}}

The third and final:

i = 0
array[0] is 1
list = {value: 1, rest: {value: 2, rest: {value: 3, rest: null}}}

As for printing undefined, I don't understand why, but this works:

    function arrayToList(array) 
    {
      var list = null;
      for (var i = array.length-1; i>=0; i--) {
          list = {value: array[i], rest: list};
      }
      return list;
    }

    $('#A').html(JSON.stringify(arrayToList([1, 2, 3])));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="A">test</div>

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

5 Comments

Yep, I understood how the steps work and how the objects point to one another but why is a new list object created each time and the existing list is put into the rest property, instead of the existing one being overwritten by the new one?
Because the whole right hand side expression of the assignment is evaluated/executed before it is actually assigned to the left hand side variable. So while the new object is being constructed, the old one is untouched and so it's value can be used during that construction.
just like var a = 1; a = 1 + a; a will be 2 after this, its value doesn't change until after the right hand side is evaluated. The list is the same, we're not editing list, we're changing what it is a reference to. I.e. it was a reference to {value: 3, rest: null} now it's a reference to a new object {value: 2, rest: {value: 3, rest: null}}. Hope that helps
So, are you saying that first {value: array[i], rest: list} object is created and the previous list is put in the rest property? And only then a new list variable that points to the object is created?
Almost, except there is no new list variable. There is only one variable and it is updated to reference the new object.

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.