cresjoy cresjoy - 5 months ago 11
Javascript Question

Going from an list to an array

So I'm working on a problem and I successfully solved the first part, which allowed me to add some types to an object as here

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


Now this works fine and all, but now I'm trying to make another function concurrently which does the opposite. The solution is here

function listToArray(list) {
var array = [];
for (var node = list; node; node = node.rest)
array.push(node.value);
return array;
}


Could someone please explain how this for loop works? I don't understand the structure of this for loop and I looked on w3 schools for an example similar to this. Why is the second parameter of the for loop a variable? Also why is the third parameter equating our variable to a type?

Answer

Explanation

For loops contain 3 statements in their body:

for (initialization; condition; final-expression)

I think you understand how initialization and final-expression work, but the condition is the test that determines whether the for loop continues iterating or terminates.

Since node can be an object or null in this case, those are "truthy" and "falsy" values. Boolean(null) === false, so if the current iteration has landed on a null, it knows that the linked list has ended and it can stop looping.

Walkthrough

Alright, so the reason why the second for loop starts with node = list is because list is an object that needs to be traversed. Notice that the next node is always contained in node.rest. So in order to "increment", we need to assign node.rest to node using node = node.rest. Now we understand these parts:

for (var node = list; ... ; node = node.rest)

The remaining part is the statement that checks whether the for loop should continue or terminate. We know that if node is null, then there are no more nodes left to traverse, so we can check that. In JavaScript, since Boolean(null) === false, we can simply assert that node is "truthy" to contiunue, since Boolean({}) === true. So the statement node just checks whether to continue or not:

for (var node = list; node; node = node.rest)

Demo

One of the most informative things to do when learning a language construct is to run the code and see what the output looks like yourself. In this example, the array is

["hello", "world", "how", "are", "you", "today"]

and the list is

{"value": "hello", "rest": {"value": "world", "rest": {"value": "how", "rest": {"value": "are", "rest": {"value": "you", "rest": {"value": "today", "rest": null}}}}}}

/* ignore this */
console.log = function (data) {
  if (typeof data === 'object') {
    data = JSON.stringify(data, null, 2);
  }
  
  document.write('<pre>' + data + '</pre>');
}

/* pay attention to everything below here */
function arrayToList(array) {
  console.log('arrayToList\n\n');

  var list = null;
  for (var i = array.length - 1; i >= 0; i--) {
    list = {value: array[i], rest: list};
    console.log('index: ' + i);
    console.log('value: ' + JSON.stringify(array[i]));
    console.log(list);
    console.log('-----');
  }
  
  return list;
}

function listToArray(list) {
  console.log('listToArray\n\n');

  var array = [];
  for (var node = list; node; node = node.rest) {
    array.push(node.value);
    console.log('index: ' + (array.length - 1));
    console.log('value: ' + JSON.stringify(array.slice(-1)[0]));
    console.log(node);
    console.log('-----');
  }

  return array;
}

var array = ['hello', 'world', 'how', 'are', 'you', 'today'];

var list = arrayToList(array);

listToArray(list);
pre {
  margin: 0;
  padding: 0;
}