reptile7's JavaScript blog
Monday, August 18, 2014
The Hyperlink Shuffle, Part 2
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... );


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:

This is True
The Dilbert Zone
Centre for The Easily Amused

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

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)