Using for loops to define global variables - javascript

I am defining some global arrays at the top of my JS file. There are for loops to populate the arrays. I have done very similar things that have worked but for some reason, this is having issues. The first for loop runs through only one time and the code below that never gets ran.
var group = 'a';
var RoofVar = 1;
var TrimVar = 1;
var BBVar = 1;
var imageArrayGroup0 = [];
var floatingButtonArrayGroup0 = [];
var labelArrayGroup0 = [];
for (a = 1; a < 3; a++) {
labelArrayGroup0[a] = document.createElement("Label");
labelArrayGroup0[a].type = "Label";
floatingButtonArrayGroup0[a] = document.getElementById('floatingButton0' + (100 + a));
floatingButtonArrayGroup0[a].style.textAlign = "center";
floatingButtonArrayGroup0[a].style.paddingTop = "5px";
labelArrayGroup0[a] = document.getElementById('floatingButton0' + (100 + x));
}
var imageArray0 = [];
var floatingButtonArray0 = [];
var labelArray0 = [];
for (b = 1; b < 5; b++) {
imageArray0[b] = document.createElement("img");
imageArray0[b].type = "image";
floatingButtonArray0[b] = document.getElementById('floatingButton0' + (b));
floatingButtonArray0[b].style.paddingLeft = "15px";
floatingButtonArray0[b].style.paddingTop = "5px";
labelArray0[b] = document.getElementById('floatingButton0' + b);
}
var imageArray1 = [];
var floatingButtonArray1 = [];
var labelArray1 = [];
for (c = 1; c < 3; c++) {
imageArray1[c] = document.createElement("img");
imageArray1[c].type = "image";
floatingButtonArray1[c] = document.getElementById('floatingButton1' + (c));
floatingButtonArray1[c].style.paddingLeft = "15px";
floatingButtonArray1[c].style.paddingTop = "5px";
labelArray1[c] = document.getElementById('floatingButton1' + c);
}

You have other issues than just "(100 + x) instead of (100 + a).
First, arrays in JavaScript are "zero-based" but your loops start at 1.
This means you're putting things in but leaving spot '0' undefined, which will probably break things later.
Next. at the beginning of the loop you set labelArrayGroup0[a] to a new blank label, but you never do anything to put it on the page. At the end the loop, you overwrite labelArrayGroup0[a] to a floatingButton element you pull from the page.
In fact, you do this in every loop - the last line resets the value of the 1st line.
It's not clear what you're trying to accomplish. Presumably you intend to append labelArrayGroup0[a] to the page instead?
Also, in the middle, you set floatingButtonArrayGroup0[a] = document.getElementById('floatingButton0' + (100 + a)); which is the same element you grab in the last line of the loop...

Paul had my answer. I forgot to switch out the "x" for an "a".

Related

How do I cycle through multiple lines with a javascript letter randomiser?

Ok so I have this code for a JavaScript letter randomiser that works perfectly fine, i'm just having trouble figuring out how i'd get it to produce more than just one line while still keeping my code relatively efficient.
Ideally id like it to say something like this and then cycle back to the start:
Hi, my name is Yeet
this is my website
I like making cool stuff
take a look around :)
Any help would be greatly appreciated :)))
window.onload = function() {
var theLetters = "abcdefghijklmnopqrstuvwxyz#%&^+=-";
var cntnt = "Hi, my name is Yeet";
var speed = 20; // ms per frame
var increment = 2; // frames per step
var clen = cntnt.length;
var si = 0;
var stri = 0;
var block = "";
var fixed = "";
//Call self x times, whole function wrapped in setTimeout
(function rustle(i) {
setTimeout(function() {
if (--i) {
rustle(i);
}
nextFrame(i);
si = si + 1;
}, speed);
})(clen * increment + 1);
function nextFrame(pos) {
for (var i = 0; i < clen - stri; i++) {
var num = Math.floor(theLetters.length * Math.random());
//Get random letter
var letter = theLetters.charAt(num);
block = block + letter;
}
if (si == (increment - 1)) {
stri++;
}
if (si == increment) {
// Add a letter;
// every speed*10 ms
fixed = fixed + cntnt.charAt(stri - 1);
si = 0;
}
$("#output").html(fixed + block);
block = "";
}
};
Make cntnt an array
var cntnt = ["Hi, my name is Yeet", "This is my website", "I like making cool stuff", "take a look around :)"];
and use pos % cntnt.length as the array index.
fixed = fixed + cntnt[pos % cntnt.length].charAt(stri - 1);

Using RegExp With Replace and Arrays

I am running a RegExp on a user input to test for capitals of 3 or more in a row. I have a loop that finds the RegExp and then adds it to an array. Another loop that creates a new array. When I run the .replace it seems that that array isn't being looped over.
var abbrBracket = /\([A-Z]{3,30}\)/g;
var abbrBracketArr = [];
var a;
while (a = abbrBracket.exec(nonCode)) {
abbrBracketArr.push(a[0]);
}
var capFoundInArr = /[A-Z]{3,30}/g;
var abbrBracketArrRemove = [];
var b;
while (b = capFoundInArr.exec(abbrBracketArr)) {
abbrBracketArrRemove.push('(<abbr>' + b[0] + '</abbr>)');
}
for(var c = 0; c < abbrBracketArrRemove.length; c++){
nonCode = document.getElementById('cleanse').innerHTML;
//nonCode = nonCode.replace(new RegExp(/\([A-Z]{3,30}\)/), abbrBracketArrRemove[c]);
nonCode = nonCode.replace(new RegExp(abbrBracketArr[c]), abbrBracketArrRemove[c]);
document.getElementById('cleanse').innerHTML = nonCode;
}
The results show if there are two (or more) of the same abbreviations, the first is executed multiple times the next is skipped.
Saying that, I am using the exact same code to run a second query for replace and I am not getting this error.
var abbrNoBracket = /\s[A-Z]{3,30}/g;
var abbrNoBracketArr = [];
var d;
while (d = abbrNoBracket.exec(nonCode)) {
abbrNoBracketArr.push(d[0]);
}
var abbrNoBracketArrRemove = [];
var e;
while (e = capFoundInArr.exec(abbrNoBracketArr)) {
abbrNoBracketArrRemove.push(' <abbr title="">' + e[0] + '</abbr>');
}
for(var f = 0; f < abbrNoBracketArrRemove.length; f++){
nonCode = document.getElementById('cleanse').innerHTML;
nonCode = nonCode.replace(new RegExp(abbrNoBracketArr[f]), abbrNoBracketArrRemove[f]);
document.getElementById('cleanse').innerHTML = nonCode;
}
In the first block, you can see I commented out a line, if I use the RegExp instead of the array. It works. Curious, why this would work for one, but not the other.
Found my error, which was very obvious after a good nights sleep.
I called a new RegExp on the array. Once I removed that, everything worked as it should.
for(var c = 0; c < abbrBracketArrRemove.length; c++){
nonCode = document.getElementById('cleanse').innerHTML;
//mistake
//nonCode = nonCode.replace(new RegExp(abbrNoBracketArr[f]), abbrNoBracketArrRemove[f]);
//corrected
nonCode = nonCode.replace(abbrBracketArr[c], abbrBracketArrRemove[c]);
document.getElementById('cleanse').innerHTML = nonCode;
}
Hopefully that helps someone else.

Setting the value in a for loop in Javascript

I have a for loop that i need to increase the value of on each iteration, and a few examples of what I have tried so far. I need to increase the value of tp on each loop through:
for (var t = 9; t < 20; t++) {
//Tried the below:
var timePeriod = report_data[i] + '.tp' + t.toString();
venues[i].scan_times[t] = timePeriod;
//and:
venues[i].scan_times[t] = report_data[i].tp + t;
}
The manual way of doing it, which I am trying to use the for loop to accomplish:
venues[i].scan_times['9'] = report_data[i].tp9;
venues[i].scan_times['10'] = report_data[i].tp10;
....
venues[i].scan_times['19'] = report_data[i].tp19;
venues[i].scan_times['20'] = report_data[i].tp20;
In javascript you can always access attributes in two ways: with bracket notation and dot notation
var myObj = {};
// those 2 lines are equivalent
myObj.a = 1;
myObj['a'] = 1
If you want to dynamically access some attributes you can use whatever you want inside the brackets.
// those 2 lines are equivalent
myObj['a' + 4] = 1;
myObj.a4 = 1;
In your case you can write
for (var t = 9; t < 20; t++) {
venues[i].scan_times[t] = report_data[i]['tp' + t];
}

Working with 2-D arrays in JS

I know that multi-dimensional arrays are not natively supported in JS, but I would like to shoehorn them in a calculation I'm doing. For example, I have:
amn1 = new Array(4);
for (j = 0; j < amn1.length; j = j + 1) {
amn1[j] = new Array(4);
}
amn1[0][0] = -8.72500;
amn1[0][1] = 1.88000;
amn1[0][2] = 0.741900;
amn1[0][3] = 0.752000;
amn1[1][0] = 0.83090;
amn1[1][1] = 0.11140;
amn1[1][2] = -0.528800;
amn1[1][3] = -0.555890;
amn1[2][0] = -0.13396;
amn1[2][1] = -0.06481;
amn1[2][2] = 0.126423;
amn1[2][3] = 0.128431;
amn1[3][0] = 0.01262;
amn1[3][1] = 0.00540;
amn1[3][2] = -0.009341;
amn1[3][3] = -0.009306;
for (u = 0; u < 4; u = u + 1) {
for (n = 0; n < 4; n = n + 1) {
amn1[u][n] = amn1[u][n] * logt + amn1[u][n];
}
loglambda = loglambda + amn1[u][n];
loglambda = loglambda * logi;
}
Assume my script is linted and all variables are properly declared and initialized. Now, checking to see if JS understands the contents of amn1 in the inner loop, it does. However, in the outer loop a check of the console output reveals undefined. Keeping the logic the same, this works in a procedural language, but not here (I have a working version of this in Fortran).
Why does this not work?
dead simple :
loglambda = loglambda + amn1[u][n];
on that line your N will always be 4.
Keeping in mind the size of your array : you have only j = [0,1,2,3] for each amn1[i][j].

For Loops inside For Loops inside For Loops... = Problems

So. I have 4 for loops inside other for loops in JS, and my code appears (FireBug agrees with me) that my code is syntactically sound, and yet it refuses to work. I'm attempting to calculate the key length in a vigenere cipher through the use of the Index of Coincidence, and Kappa tests <- if that helps any.
My main problem is that the task seems to be too computationally intensive for Javascript to run, as Firefox shoots up past 1GB of memory usage, and 99% CPU when I attempt to run the keylengthfinder() function. Any ideas of how to solve this problem, even if it takes much longer to calculate, would be greatly appreciated. Here's a link to the same code - http://pastebin.com/uYPBuZZz - Sorry about any indenting issues in this code. I'm having issues putting it on the page correctly.
function indexofcoincidence(text){
text = text.split(" ").join("").toUpperCase();
var textL = text.length;
var hashtable = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (d=0; d<=25; d++) {
for (i=0; i < textL; i++){
if (text.charAt(i) === alphabet.charAt(d)){
hashtable[d] = hashtable[d] + 1;
}
}
}
var aa = hashtable[0]/textL;
var A = aa*aa;
var bb = hashtable[1]/textL;
var B = bb*bb;
var cc = hashtable[2]/textL;
var C = cc*cc;
var dd = hashtable[3]/textL;
var D = dd*dd;
var ee = hashtable[4]/textL;
var E = ee*ee;
var ff = hashtable[5]/textL;
var F = ff*ff;
var gg = hashtable[6]/textL;
var G = gg*gg;
var hh = hashtable[7]/textL;
var H = hh*hh;
var ii = hashtable[8]/textL;
var I = ii*ii;
var jj = hashtable[9]/textL;
var J = jj*jj;
var kk = hashtable[10]/textL;
var K = kk*kk;
var ll = hashtable[11]/textL;
var L = ll*ll;
var mm = hashtable[12]/textL;
var M = mm*mm;
var nn = hashtable[13]/textL;
var N = nn*nn;
var oo = hashtable[14]/textL;
var O = oo*oo;
var pp = hashtable[15]/textL;
var P = pp*pp;
var qq = hashtable[16]/textL;
var Q = qq*qq;
var rr = hashtable[17]/textL;
var R = rr*rr;
var ss = hashtable[18]/textL;
var S = ss*ss;
var tt = hashtable[19]/textL;
var T = tt*tt;
var uu = hashtable[20]/textL;
var U = uu*uu;
var vv = hashtable[21]/textL;
var V = vv*vv;
var ww = hashtable[22]/textL;
var W = ww*ww;
var xx = hashtable[23]/textL;
var X = xx*xx;
var yy = hashtable[24]/textL;
var Y = yy*yy;
var zz = hashtable[25]/textL;
var Z = zz*zz;
var Kappa = A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z;
var Top = 0.027*textL;
var Bottom1 = 0.038*textL + 0.065;
var Bottom2 = (textL - 1)*Kappa;
var KeyLength = Top/(Bottom2 - Bottom1) ;
return Kappa/0.0385;
}
function keylengthfinder(text){
// Average Function Definition
Array.prototype.avg = function() {
var av = 0;
var cnt = 0;
var len = this.length;
for (var i = 0; i < len; i++) {
var e = +this[i];
if(!e && this[i] !== 0 && this[i] !== '0') e--;
if (this[i] == e) {av += e; cnt++;}
}
return av/cnt;
}
// Begin the Key Length Finding
var textL = text.length;
var hashtable = new Array(0,0,0,0,0,0,0,0,0,0,0,0);
for (a = 0; a <= 12; a++){ // This is the main loop, testing each key length
var stringtable = [];
for (z = 0; z <= a; z++){ // This allows each setting, ie. 1st, 4th, 7th AND 2nd, 5th, 8th to be tested
for (i = z; i < textL; i + a){
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
}
}
hashtable[a] = stringtable.avg();
}
return hashtable;
}
Your problem is definitely right here
for (i = z; i < textL; i + a){
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
}
Notice that if a=0 i never changes and therefore you are in an infinite loop.
Array.prototype.avg = function() {...}
should be only done once, and not every time keylengthfinder is called.
var Top = 0.027*textL;
var Bottom1 = 0.038*textL + 0.065;
var Bottom2 = (textL - 1)*Kappa;
var KeyLength = Top/(Bottom2 - Bottom1) ;
return Kappa/0.0385;
Why do you computer those variables if you don't use them at all?
var string = '';
string = string.concat(text.charAt(i)); // Join each letter of the correct place in the string
stringtable[z] = indexofcoincidence(string);
I don't know what you are trying to do in here. The string will always be only one character?
for (i = z; i < textL; i + a) {
...
stringtable[z] = ...
}
In this loop, you are computing values for i from z to textL - but you overwrite the same array item each time. So it would be enough to compute the stringtable[z] for i=textL-1 - or your algorithm is flawed.
A much shorter and more concise variant of the indexofcoincidence function:
function indexofcoincidence(text){
var l = text.replace(/ /g, "").length;
text = text.toUpperCase().replace(/[^A-Z]/g, "");
var hashtable = {};
for (var i=0; i<l; i++) {
var c = text.charAt(i);
hashtable[c] = (hashtable[c] || 0) + 1;
}
var kappa = 0;
for (var c in hashtable)
kappa += hashtable[c] * hashtable[c];
return kappa/(l*l)/0.0385;
}
All right. Now that we found your problem (including the infinite loop in case a=0, as detected by qw3n), let's rewrite the loop:
function keylengthfinder(text) {
var length = text.length,
probabilities = []; // probability by key length
maxkeylen = 13; // it might make more sense to determine this in relation to length
for (var a = 1; a <= maxkeylen; a++) { // testing each key length
var stringtable = Array(a); // strings to check with this gap
// read "a" as stringtable.length
for (var z = 0; z < a; z++) {
var string = '';
for (var i = z; i < textL; i += a) {
string += text.charAt(i);
}
// a string consisting of z, z+a, z+2a, z+3a, ... -th letters
stringtable[z] = string;
}
var sum = 0;
// summing up the coincidence indizes for current stringtable
for (var i=0; i<a; i++) {
sum += indexofcoincidence(stringtable[i]);
}
probabilities[a] = sum / a; // average
}
return probabilities;
}
Every of the loop statements has changed against your original script!
Never forget to declare the running variable to be local (var keyword)
a needs to start at zero - a key must have a minimum length of 1
to run from 1 to n, use i=1; i<=n; i++
to run from 0 to n-1, use i=0; i<n; i++ (nearly all loops, especially on zero-based array indizes).
Other loops than those two never occur in normal programs. You should get suspicious if you have loops from 0 to n or from 1 to n-1...
The update expression needs to update the running variable. i++ is a shortcut for i+=1 is a shortcut for i=i+1. Your expression, i + a, did not assign the new value (apart from the a=0 problem)!

Categories

Resources