Monday, August 18, 2014

Blog Entry #331

Welcome back to our ongoing analysis of the New Array Text Pages RandomLinks.html script. In today's post we'll take a detailed look at the script's buildArrayofRandomValues( ) function.

```function buildArrayofRandomValues(length) { RandomIdx = 0; for (i = 0; i < length; i++) { RandomValue[i] = -1; while (RandomValue[i] == -1) { r = Math.floor(Math.random( ) * length); for (j = 0; j <= i && RandomValue[j] !=r; j++) { if (j == i) RandomValue[i] = r; } } } }```

The buildArrayofRandomValues( ) function individually populates the RandomValue[0] → RandomValue[4] array boxes with the numbers 0, 1, 2, 3, and 4, but in a random order.

As noted at the end of the previous post, the buildArrayofRandomValues( ) call follows the creation of the URLlist data structure.

```var RandomValue = new Array( ); var RandomIdx; function buildArrayofRandomValues(length) { ... } var URLlist = new linkArray( ...Link data... ); buildArrayofRandomValues(URLlist.length);```

The URLlist length (5) is passed to the buildArrayofRandomValues( ) function and given a length identifier.

The buildArrayofRandomValues( ) body's first statement initializes the RandomIdx variable to 0.

`RandomIdx = 0;`

The buildArrayofRandomValues( ) function makes no use of RandomIdx, however. RandomIdx plays a starring role in a randomIndex( ) function that we'll briefly discuss later.

The rest of buildArrayofRandomValues( ) comprises a for loop

`for (i = 0; i < length; i++) { ... }`

whose i counter determines the size of the RandomValue array. The loop does not iterate over the `link` objects: we'll apply the RandomValue array to those objects when we write the linkToString( ) anchor element(s) to the page.

The loop initializes RandomValue[i] to -1 and then sets in motion a while loop that runs until a new 0|1|2|3|4 number for RandomValue[i] is found.

```RandomValue[i] = -1; while (RandomValue[i] == -1) { ... }```

We can throw out the `RandomValue[i] = -1;` assignment if we change the while condition to `RandomValue[i] == undefined`.
N.B. Use of a `! RandomValue[i]` condition causes the browser to hang. Although undefined converts to false in a boolean context, so does 0, and (without getting into the details) the latter conversion gives rise to an infinite loop.

The while loop begins by getting a random integer in the range 0-4, inclusive; the integer is assigned to an r variable.

`r = Math.floor(Math.random( ) * length);`

• The Math.random( ) command returns a pseudo-random floating-point number in the range 0 ≤ x < 1.
• The `* length` multiplication takes us to a 0 ≤ x < 5 floating-point number.
• The Math.floor( ) operation takes us to a 0 ≤ x ≤ 4 integer.

Subsequently another for loop

```for (j = 0; j <= i && RandomValue[j] != r; j++) { if (j == i) RandomValue[i] = r; }```

uses a j variable to see if r's value has hitherto been loaded into any RandomValue[ ] boxes: if not, then r is assigned to RandomValue[i].

Re the `j <= i && RandomValue[j] != r` for condition, the <= and != comparison operators take precedence over the && logical operator and thus there is no need to parenthesize the comparisons although you can certainly do so if you feel it would improve the code's readability:

`for (j = 0; (j <= i) && (RandomValue[j] != r); j++) { if (j == i) RandomValue[i] = r; }`

During the outer for loop's i = 0 iteration, the while loop and the inner for loop each run for one iteration. Let's say the first r return is 3. For j = 0, the `j <= i && RandomValue[j] != r` and `j == i` conditions return true and consequently 3 is assigned to RandomValue[0].

Proceeding to the outer for loop's i = 1 iteration, suppose the next r return is again 3. In this case the inner for loop's `RandomValue[j] != r` subcondition (and therefore the `j <= i && RandomValue[j] != r` condition as a whole) returns false from the get-go, so the while loop gets another r value.

Suppose the third r return is 1. The inner for loop runs for two iterations; in the j = 1 iteration, `j == i` returns true and RandomValue[1] is set to 1.

And so on. By and by all five 0/1/2/3/4 numbers come up and are loaded into the RandomValue array. You can see the array value order by putting a `window.alert(RandomValue.join( ))` command after the buildArrayofRandomValues( ) call.

Display it

When the outer for loop has finished executing and the RandomValue array is complete, we are ready to convert the `link` objects into bona fide HTML links and then write the latter to the page in a random order.

```for (i = 0; i < URLlist.length; i++) { document.write(URLlist[randomIndex( )] + "<br>"); }```

A five-iteration for loop calls on a randomIndex( ) function

```function randomIndex( ) { RandomIdx++; RandomIdx = RandomIdx % RandomValue.length; return RandomValue[RandomIdx]; }```

that increments RandomIdx, modulos RandomIdx by RandomValue.length, and plugs the modulo remainder into RandomValue[ ] so as to access the RandomValue elements in a [1]-[2]-[3]-[4]-[0] order. The randomIndex( ) returns are plugged into URLlist[ ] to give a random series of `link` objects that are HTML-ized* and printed out via the document.write( ) command.

*The string context of the write( ) command automatically triggers the objects' toString( ) functionality.

The absence of the i counter in the loop body raises a red flag. Why are we reaching for RandomValue with an external function? Loops and arrays are meant for each other: clearly, it would be better to step through RandomValue 'in-house'.

`for (i = 0; i < URLlist.length; i++) { document.write(URLlist[RandomValue[i]] + "<br>"); }`

The loop displays the `link` links as a list:

The links can also be embedded in the document text: we'll see how to do this in the following entry.