javascript variable concatenation in loop - javascript

How am I supposed to concatenate this?
here's my javascript code
var c0 = document.all.ntext.value;
var c1 = document.all.stext.value;
var x;
for(x=0; x<2; x++)
{
a.innerHTML = c //contatenation needed
}

var c0 = document.all.ntext.value;
var c1 = document.all.stext.value;
var x;
for(x=0; x<2; x++)
{
a.innerHTML = c0 + с1
}
Is that what you want?
It'll be much better if you'll go this way:
var c = [document.all.ntext.value, document.all.stext.value];
var x;
for(x=0; x<c.length; x++)
{
a.innerHTML += c[0];
}

var needed = ['ntext', 'stext'];
a.innerHTML = needed.map(function(key) {
return document.all[key].value;
}).join('');
.map need a shim for old browsers.

Related

What's the best way to allocate the variables with multiple combinations

I want to reduce the initialization of multiple combination variables.
My aim is to create a function and pass a function with variable.
If I pass a variable x into function value(x); I should get output as "123". Similarly, if I pass a variable xy into function value(xy), then I should get output as "123456". Basically, I want to concatenate variables
Here is the javascript code as
var x = "123";
var y = "456";
var z = "789";
var a = "0-+";
var xy = x + y;
var yz = y + z;
var zx = z + x;
var xa = x + a;
var ya = y + a;
var za = z + a;
var ax = a + x;
var ay = a + y;
var az = a + z;
var xz = x + z;
var yx = y + x;
var zx = z + x;
var zy = z + y;
var xyz = x + y + z;
var xyza = x + y + z + a;
function value(input) {
console.log(input);
}
Sample execution as follows:
value(x); //output: 123
value(y); //output: 456
value(xy); //output: 123456
value(za); //output: 7890-+
In this case, there are lots of combination for the above variables i have defined to meet all possible combinations. I want to validate the user input from the above combination and also i dont want to write so many variables. Is there any possible easy solution ?
Please suggest. Thanks
I would declare a global object to store the variables as keys:
var globals = {
"x": "123",
"y": "456",
"z": "789"
};
Note that you can refer to your "variables" by globals.x, or globals.y (you can replace globals with a shorter keywork to reduce code of course).
It is a little extra effort to define the "variable names" with quotes.
However, now you get to use:
alert(Combinate("xz"));
// output: 123789
With a function like:
function Combinate(phrase) {
result = "";
for (var i = 0, len = phrase.length; i < len; i++) {
result += globals[phrase[i]];
}
return result;
}
Here's a JSFiddle.
You'll want to use some form of iterating over an array or object. As an example:
var x = "dave";
var y = "bill";
var z = "john";
var a = "suzan";
var people = [x,y,z,a];
for(i=0; i<people.length; i++) {
for(x=0; x<people.length; x++) {
value(people[i] + people[x]);
for(y=0; y<people.length; y++) {
value(people[i] + people[x] + people[y]);
for(z=0; z<people.length; z++) {
value(people[i] + people[x] + people[y] + people[z]);
}
}
}
}
// not sure why you'd have a function to wrap console.log(), but...
function value(input) {
console.log(input);
}
See in action on jsFiddle.
There are more elegant paths, but this should get you on the road to learning about JavaScript.

Random path in svg in javascript

I wrote the following javaScript to try to draw a random path in an svg.
<script>
window.onload = function() {
function randomPath(){
var x = Math.trunc(Math.random());
var y = Math.trunc(Math.random());
var xstep = 0;
var ystep = 0;
var path = '0,0';
for (i = 0; i < 2 ; i++) {
path += ' ';
path += (x).toString();
path += ',';
path += (y).toString();
xstep = Math.random();
ystep = Math.random();
xstep *= 10;
ystep *= 10;
x += Math.trunc(xstep);
y += Math.trunc(ystep);
};
return path;
};
var figure = document.createElementNS('http://www.w3.org/2000/svg','svg');
figure.id = 'brownian-figure';
figure.setAttribute('height', '400pt');
figure.setAttribute('width', '200pt');
var pathArray = [];
for (i = 0; i < 3; i++){
pathArray[i] = document.createElementNS('http://www.w3.org/2000/svg','polyline');
};
for (i = 0; i < 3; i++){
var path = randomPath();
alert(path);
pathArray[i].setAttribute('points', path);
pathArray[i].setAttribute('style', 'fill:none;stroke:rgba(0,0,0,1);stroke-width:1');
figure.appendChild(pathArray[i]);
};
var divfigure = document.createElement('div');
divfigure.id = 'divfigure';
divfigure.style = 'margin:0pt;padding:0pt;border:0pt none;background-color:rgba(240,240,240,1);position:absolute;top:100pt;left:100pt;width:200pt;height:400pt;';
divfigure.appendChild(figure);
document.body.appendChild(divfigure);
};
</script>
Notice there are only 2 steps in the for in the randomPath() function.
The code does run and draws with that small value for the number of steps. There is an alert(path) over there to let me see the path before I try to assign it.
However, with 3 steps or more in the for inside randomPath() the code breaks. The alert(path) still shows the longer path, but the script gives the error
TypeError: pathArray[i] is undefined
pathArray[i].setAttribute('points', path);
If I replace path in the line with the error, by an explicit path (output by randomPath()), say '0,0 0,0 4,8 8,15' it still doesn't work. But if I do it and also remove the call to the randomPath() function it works again.
I am confused. It seems to be that the function randomPath() works well since the alert displays a well-formed string. The svg also works with the same string input explicitly. But the two together don't work for some reason.
What is the problem?
The problem is becoz inside last for loop you have initialise i and incremented it and then you call randomPath() which also contain i and that function increment it to 3 times so when it comes out function you have i value 3
so you get error on pathArray[i].setAttribute('points', path); changed it to k or something in randomPath() and also intialize variable as var identifier if don't want it to be global
for (i = 0; i < 3; i++){
var path = randomPath();
}
window.onload = function() {
function randomPath(){
var x = Math.trunc(Math.random());
var y = Math.trunc(Math.random());
var xstep = 0;
var ystep = 0;
var path = '0,0';
for (k = 0; k < 3 ; k++) {
path += ' ';
path += (x).toString();
path += ',';
path += (y).toString();
xstep = Math.random();
ystep = Math.random();
xstep *= 10;
ystep *= 10;
x += Math.trunc(xstep);
y += Math.trunc(ystep);
}
return path;
}
var figure = document.createElementNS('http://www.w3.org/2000/svg','svg');
figure.id = 'brownian-figure';
figure.setAttribute('height', '400pt');
figure.setAttribute('width', '200pt');
var pathArray = [];
for (j = 0; j < 3; j++){
pathArray[j] = document.createElementNS('http://www.w3.org/2000/svg','polyline');
}
for (i = 0; i < 3; i++){
var path = randomPath();
alert(path);
pathArray[i].setAttribute('points', path);
pathArray[i].setAttribute('style', 'fill:none;stroke:rgba(0,0,0,1);stroke-width:1');
figure.appendChild(pathArray[i]);
}
var divfigure = document.createElement('div');
divfigure.id = 'divfigure';
divfigure.style = 'margin:0pt;padding:0pt;border:0pt none;background-color:rgba(240,240,240,1);position:absolute;top:100pt;left:100pt;width:200pt;height:400pt;';
divfigure.appendChild(figure);
document.body.appendChild(divfigure);
};

How to take plus sign in variable

I want to calculate two numbers and its pretty simple.
But Is there any way to take operator in variable and then do the calculation?
var x = 5;
var y = 5;
var p = '+';
var z = x + p + y;
$(".button").click(function() {
alert(z);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button">Click ME !</div>
Avoid eval whenever possible. For this example, a simple switch...case statement will be sufficient:
var x = 5;
var y = 5;
var z;
var p = "+";
switch (p) {
case "+":
z = x + y;
break;
case "-":
z = x - y;
break;
}
You can also use a map of functions:
var fnlist = {
"+": function(a, b) { return a + b; },
"-": function(a, b) { return a - b; }
}
var x = 5;
var y = 5;
var p = "+";
var z = fnlist[p](x, y);
Or use parseInt on the string which you will be adding the variable to:
var x = 5;
var y = 5;
var p = '-';
var z = x + parseInt(p + y);
$(".button").click(function(){
alert(z);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button">Click ME !</div>
You are looking for eval function:
var x = 5;
var y = 5;
var p = '+';
var z = x + p + y;
$(".button").click(function(){
alert(eval(z));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button">Click ME !</div>
However, you have to remember that using eval function is potentially risky. For example, if used in the wrong way it can allow one to make injection attacks. Debugging can be also more difficult. I suggest to read this question.
you can use the eval function:
var x = 5;
var y = 5;
var p = '+';
var z = eval(x + p + y);
alert(z);

JavaScript syntax issue

I'm doing "fifteen puzzle" game. I'm only a beginner, so I chose this project to implement. My problem is shuffle algorithm :
function shuffle() {
$('td').empty();
var p = 0;
var f = 0;
do {
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
var rand = arr[Math.floor(Math.random() * arr.length)];
if ($('#' + rand).is(':empty')) {
p = p + 1;
document.getElementById(rand).textContent = p
var f = $('td').not(":empty").length;
} else {}
} while (f < 15)
That works cool, but I've heard that almost 50% of all random shuffle like mine is unsolvable. So I found math formula at wikipedia.org for this game, explaining how you can avoid that.
Here's modified algorithm that doesn't work either. The way I know it is alert stuff: it launches only 2 times instead of 31.
array = [];
function algorithm (){
// alert('works')
for (var c=16; c<17; c++){
document.getElementById(c).textContent = '100';
}
for (var i=1; i<16; i++){
var curId = document.getElementById(i).id;
var curIdNum = Math.floor(curId);
alert('works')
var curIn = document.getElementById(i).textContent;
var curInNum = Math.floor(curIn);
array.push(i);
array[i] = new Array();
for (var j=1; j<15; j++){
var nextId = curIdNum + j; //curIdNum NOT cerIdNum
var nextIn = document.getElementById(nextId).textContent;
//alert('works')
if (nextId < 16){
var nextInNum = Math.floor(nextIn);
if (curInNum > nextInNum){
array[i].push(j)
}
}
}
var sum = 0;
for (var a=0; a<15; a++){
var add = array[a].length;
sum = sum + add;
}
var end = sum + 4;
if (end % 2 == 0){
document.getElementById('16').textContent = "";
}
else {
shuffle();
}
}
}
The question is the same:
What's wrong? Two-dimensional array doesn't work.If you've got any questions - ask.
Just to make it clear: 2 for loops with i and j should make a 2-dimensional array like this [ this is " var i" -->[1,3,4,5,7], this is "var i" too-->[5,7,9,14,15]]. Inside each i there's j. The for loop with var a should count the number of js inside each i. if the number of js is even, the code is finished and shuffle's accomplished, otherwise shuffle should be made once again.
var nextId = cerIdNum + j;
in that fiddle, I don't see this cerIdNum declared & defined neither as local nor as global variable, I suppose that is curIdNum
Please use the below definition of algorithm and let us know if this works. Basically, the alert messages would come only twice, since there were usages of undefined variables. For the purpose of illustration, I have placed comments at where the problem points occured. Due to these problems, your script would stop executing abruptly thereby resulting in the behavior you described.
Oh and by the way - I did not have time to go through the Wiki link provided - hence you will have to verify your logic is correct. However, I have definitely resolved the errors causing the behavior you observed.
As an aside - consider using jQuery, your code will be a lot cleaner...
function algorithm (){
// alert('works')
for (var c=16; c<17; c++){
document.getElementById(c).textContent = '100';
}
for (var i=1; i<16; i++){
var curId = document.getElementById(i).id;
var curIdNum = Math.floor(curId);
alert('works')
var curIn = document.getElementById(i).textContent;
var curInNum = Math.floor(curIn);
array.push(i);
for (var j=1; j<15; j++){
var nextId = curIdNum + j; //curIdNum NOT cerIdNum
var nextIn = document.getElementById(nextId).textContent;
//alert('works')
if (nextId < 16){
var nextInNum = Math.floor(nextIn);
if (curInNum > nextInNum){
array.push(j) //array[i].push does not make sense
}
}
}
var sum = 0;
for (var a=0; a<15; a++){
var add = array.length; //array[1].length does not make sense
sum = sum + add;
}
var end = sum + 4;
if (end % 2 == 0){
document.getElementById('16').textContent = "";
}
else {
shuffle();
}
}
}
I found the solution by totally rewriting the code. Thank everyone for help!
Here's what do work:
function shuffle (){
press = 1;
$('td').empty().removeClass();
p=0;
var f;
do {
var arr=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var rand=arr[Math.floor(Math.random()*arr.length)];
if ($('#'+ rand).is(':empty')){
p = p + 1;
document.getElementById(rand).textContent = p
var f = $('td').not(":empty").length;
}
else{}
}while(f < 15){
winChance();
}
}
function winChance (){
array = [];
for (i=1;i<16;i++){
array[i]= new Array();
var currentId = $('#' + i).attr('id');
var currentIn = $('#' + i).html()
var currentIdNum = parseInt(currentId, 10);
var currentInNum = parseInt(currentIn, 10);
for (j=1;j<16;j++){
var nextId = currentIdNum + j;
if (nextId < 16){
var nextIn = $('#' + nextId).html();
var nextInNum = parseInt(nextIn, 10);
if (currentInNum > nextInNum){
array[i].push(j);
}
}
}
}
checkSum();
}
function checkSum(){
var sum = 0;
for (var a=1; a<16; a++){
var add = array[a].length;
sum = sum + add;
}
var end = sum + 4;
if (end % 2 == 0){}
else {
shuffle();
}
}

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