Couple of questions about code that hides text strings from output - javascript

Hello I started learning JavaScript and esterday I asked to help me hide NaN strings of array from output. Some guys helped me.. But I got new questions.
Here the link to answers
For this code,
if (typeof(degFahren[loopCounter]) === 'string') continue;
What's happening in there? As I can see If degFahren equal to text string, script will go ahead, but it works another way around and handle numbers for output.
For this code
if (parseInt(degFahren[loopCounter]) != "NaN")
It doesnt hide NaN strings at all. Shows all strings from array. Why?
Here block of code that does't work
for (loopCounter = 0; loopCounter <=6; loopCounter++){
if (parseInt(degFahren[loopCounter]) != "NaN")
degCent[loopCounter] = convertToCentigrade(degFahren[loopCounter]);
document.write ("Value " + loopCounter + " was " + degFahren[loopCounter] + " degrees Fahrenheit");
document.write (" which is " + degCent[loopCounter] + " degrees centigrade<br />");
}

Your assumptions are right, but the code fails because you missed the braces. You should add braces after if condition
for (loopCounter = 0; loopCounter <=6; loopCounter++){
if (parseInt(degFahren[loopCounter]) != "NaN") {
degCent[loopCounter] = convertToCentigrade(degFahren[loopCounter]);
document.write ("Value " + loopCounter + " was " + degFahren[loopCounter] + " degrees Fahrenheit");
document.write (" which is " + degCent[loopCounter] + " degrees centigrade<br />");
}
}

As I can see If degFahren equal to text string, script will go ahead
degFahren is apparently expected to be an array. It doesn't test whether degFahren is a string, it tests whether the current element being iterated over (which is inside the array) is a string.
It doesnt hide NaN strings at all. Shows all strings from array. Why?
NaN is not a string; it is a primitive value. But NaN !== NaN; you should use the isNaN() function instead.
You should also avoid implicitly creating global variables. It will be easier to read if you abstract the temperatures instead of messing with indicies:
for (loopCounter = 0; loopCounter <=6; loopCounter++){
const tempF = degFahren[loopCounter];
if (isNaN(tempF)) continue;
const tempCentigrade = convertToCentigrade(tempF);
document.write ("Value " + loopCounter + " was " + tempF + " degrees Fahrenheit");
document.write (" which is " + tempCentigrade + " degrees centigrade<br />");
}

Related

Javascript switch(true) executes false statements?

Im looping over a collection of coordinate values and doing math on the coordinates to see if the calculated values are in a hashmap. if they are in the hash map then I want to run an additional function. since I had multiple cases I wanted to check for each coord in the collection, I figured a switch statement would be cool to use to replace my if statements so all my checks could be visually and logically grouped. When I replaced my if statements with a switch, my code returned bad results. When I debugged, I realized the switch statements would sometimes execute even when the case was false(I added console.logs to output the result of the same switch condition and it would print false, but should only run when true). Here is a small example:
var idm = {0:1, 3:1, 9:1, 10:1, 11:1, 12:1, 20:1, 21:1, 23:1}
var findNeighbors = function(b) {
var u,d,l,r,lRow,rRow;
var currentBuilding = parseInt(b);
var currRow = Math.floor(currentBuilding/column);
//remove value from map so we dont recount it.
delete idm[currentBuilding];
u = currentBuilding - column;
d = currentBuilding + column;
l = currentBuilding - 1;
lRow = Math.floor(l/column);
r = currentBuilding + 1;
rRow = Math.floor(r/column);
console.log("current idx:" + currentBuilding);
console.log("u:" + u + ", d:" + d + ", l:" + l + " r:" + r);
// debugger;
switch(true) {
case (idm.hasOwnProperty(u) === true):
console.log((idm.hasOwnProperty(u)));
console.log("map has " + currentBuilding + " -> u: " + u);
findNeighbors(u);
case (idm.hasOwnProperty(d) === true):
console.log((idm.hasOwnProperty(d)));
console.log("map has " + currentBuilding + " -> d: " + d);
findNeighbors(d);
case (lRow === currRow && idm.hasOwnProperty(l) === true):
console.log((lRow === currRow && idm.hasOwnProperty(l)));
console.log("map has " + currentBuilding + " -> l: " + l);
findNeighbors(l);
case (rRow === currRow && idm.hasOwnProperty(r) === true):
console.log((rRow === currRow && idm.hasOwnProperty(r)))
console.log("map has " + currentBuilding + " -> r: " + u);
findNeighbors(r);
}
console.log("---------------------------");
}
I figured a switch statement would be cool to use to replace my if statements so all my checks could be visually and logically grouped.
Well, write code that works not code that looks cool. You were forgetting break statements, so the execution flow fell through - without evaluating the other case expressions after the first one matched. Btw switching on a constant is a horrible (uncool) practice.
Use standard if/else instead.

If/else inside function JavaScript

Please don't be too hard on me as I've just started in school and I'm using Ubuntu. I've written this code (which might be the simplest code ever) that simply tells about the conversion of bytes into other units (Mebi, Kibi...). When I use the console.log it always displays Kibi.
function unit(x){
var x;
if (x=10){
x='Kibi';
} else if (x=20){
x='Mebi';
} else if (x=30){
x='Gibi';
}
return x;
}
console.log("2^10 bytes are 1 " + unit(10) + "byte");
console.log("2^20 bytes are 1 " + unit(20) + "byte");
console.log("2^30 bytes are 1 " + unit(30) + "byte");
The thing here is that as I said it always displays Kibi on all console outputs, the funny thing for me that I don't understand is that if I change the first console.log for
console.log('2^10 bytes are 1 ' + unit(20) + 'byte'
it will still display all console outputs with Kibi even if I never called unit(10).
I really don't understand why this is happening and any help would be greatly apprecieated. Thank you.
you've declared variable x and not set value for it, and = just for left assign follows my code
Heres my code:
function unit(x){
var nickname = '';
if (x===10){
nickname='Kibi';
} else if (x===20){
nickname ='Mebi';
} else if (x===30){
nickname ='Gibi';
}
return nickname;
}
console.log("2^10 bytes are 1 " + unit(10) + "byte");
console.log("2^20 bytes are 1 " + unit(20) + "byte");
console.log("2^30 bytes are 1 " + unit(30) + "byte");
your codes error:
variable x redeclared
x=10 means let 10 assigns to variable x.
hopes to help you
edited:
for your question, maybe this code will be better
function unit(x){
var nickname = '';
switch(x){
case 10:
nickname = 'kibi';
break;
case 20:
nickname = 'Mebi';
break;
case 30:
nickname = 'Gibi';
break;
}
return nickname;
}
console.log("2^10 bytes are 1 " + unit(10) + "byte");
console.log("2^20 bytes are 1 " + unit(20) + "byte");
console.log("2^30 bytes are 1 " + unit(30) + "byte");
I tell you
Variables should not have ambiguity, one variable do one thing.
you can follow to #epascarello and #Keith advice
All that is changed in this snippet was exactly what the two comments suggested. Remove the extra initialization of x and change "=" to "==" in the comparisons.
function unit(x){
if (x == 10){
x='Kibi';
} else if (x == 20){
x='Mebi';
} else if (x == 30){
x='Gibi';
}
return x;
}
console.log("2^10 bytes are 1 " + unit(10) + "byte");
console.log("2^20 bytes are 1 " + unit(20) + "byte");
console.log("2^30 bytes are 1 " + unit(30) + "byte");

adding and subtracting to the array range

Hey I have a question about this piece of code that I have:
var levelsRange = arrayeventslevel[0] + " through " + arrayeventslevel[arrayeventslevel.length-1]; ;
$("#existorders").html(
"There are currently: " + arrayeventslength.length +
" events on " + dayoftheweek +
"<br/>" + " with order levels: " + levelsRange +
"<br />" + "You can move new event to levels ranging between: " + newLevelsRange
);
currently levelsRange outputs for example 1 through 6 range. If that is the case,
I need another variable newLevelsRange that should say 0 through 7 based on initial variable range.
However, if levelsRangesays 0 through 6, new variable should say 0 through 7 NOT -1 through 7
I am having trouble adding subtracting properly from initial variable information. Can someone please assist.
var newLevelsRange=(arrayeventslevel[0]||1)-1 + " through " + (arrayeventslevel[arrayeventslevel.length-1]-1);
Simply check if the first element is zero, if so, take 1...
I just did this
if(arrayeventslevel[0] != 0){
arrayeventslevel[0] = arrayeventslevel[0] - 1;
arrayeventslevel.length =arrayeventslevel.length + 1;
}
var newLevelRange = arrayeventslevel[0] + " through " + arrayeventslevel.length;
not sure how to use Math.max

js last array item is undefined

I am trying to make a hangman game and in the beginning the game asks the user for the word. Once it has the word it fills the word letters one by one in an array using a for loop. Unfortunately the last array element is always undefined for some reason.
Code(JS):
for(i=0;i<word.length;i++)
{
if(i == word.length - 1)
{
wordLettersLeft = word.length;
$("#cEText").removeAttr("style");
$(".characterEnter").removeAttr("style");
$("#gBtn").text("Lopeta");
gameStarted = true;
pcArrayLength = pcArray.length;
lives = 4;
alert("Peli alkaa! Sinulla on " + lives + " yritystä jäljellä.");
alert("Vihje: " + hint);
alert("Sinulla on vielä " + wordLettersLeft + " arvattavaa kirjainta jäljellä.");
}
else
{
pcArray.push(word[i]);
}
}
This has a very simple reason: you are not adding the last letter to your pcArray. Let's assume our word is 'bird' (because bird is a word). Your code would go through the letters b, i and r and push those to your array, so far so good. But when it hits the d, it is at position word.length-1 - because the array length starts at 1 but the index starts at 0. Your if statement prevents it from pushing the last letter to the word. There are two solutions:
First, you could simply remove the else statement:
for(i=0;i<word.length;i++){
if(i == word.length - 1){
wordLettersLeft = word.length;
$("#cEText").removeAttr("style");
$(".characterEnter").removeAttr("style");
$("#gBtn").text("Lopeta");
gameStarted = true;
pcArrayLength = pcArray.length;
lives = 4;
alert("Peli alkaa! Sinulla on " + lives + " yritystä jäljellä.");
alert("Vihje: " + hint);
alert("Sinulla on vielä " + wordLettersLeft + " arvattavaa kirjainta jäljellä.");
}
pcArray.push(word[i]);
}
That will push every letter every time! However, There is a more efficient way:
for(i=0;i<word.length;i++)
pcArray.push(word[i]);
wordLettersLeft = word.length;
$("#cEText").removeAttr("style");
$(".characterEnter").removeAttr("style");
$("#gBtn").text("Lopeta");
gameStarted = true;
pcArrayLength = pcArray.length;
lives = 4;
alert("Peli alkaa! Sinulla on " + lives + " yritystä jäljellä.");
alert("Vihje: " + hint);
alert("Sinulla on vielä " + wordLettersLeft + " arvattavaa kirjainta jäljellä.");
This way you will only execute your initial code once instead of checking the if every time. You know your loop will only run for as long as there are letters, so why even bother with the if?
As #Shilly mentions in the comments, you can forego the for loop altogether by doing this:
pcArray = word.split('');
Let's say someone's inputing the word "Test". For i === 3 which is the last iteration, you enter the if clause and you're missing out on the else clause, which is where you're doing:
pcArray.push(word[i]);
What you want is to do this anyway, regardless of whether you're in the if or the else, so you can just drop the else clause and do it anyway.
The last step of your loop does not execute pcArray.push(word[i]);. So obvioulsy, the last value is missing.
But if you want to convert a string into an array, just do this :
var pcArray = word.split('');

Printing Javascript split() array and converting undefined values to strings

I am trying to convert a string to words, and then print these using javascript and html5 canvas. The string can be any length, but I am using 50 as a max value of words (separated by a space). Right now I have the following to create the array:
var wordArray = kstring.split(" ", 50);
for(var k = 0; k < wordArray.length; k++)
{
if(typeof wordArray[k] == 'undefined')
wordArray[k] = " .";
}
and then print using:
ctx.fillText(wordArray[0] + " " + wordArray[1] + " " + wordArray[2] + " " + wordArray[3] + " " + wordArray[4], leftOffset, txtHeight);
ctx.fillText(wordArray[5] + " " + wordArray[6] + " " + wordArray[7] + " " + wordArray[8] + " " + wordArray[9], leftOffset, txtHeight+20);
etc.
However, when the text prints, any undefined values print as "undefined" instead of " ." It seems that I am going about checking for the undefined value the wrong way, but I'm not sure what else to try.
Additionally, if anyone has any better suggestions for how to achieve this goal (convert a string to words and then print 5 words at a time). Please feel free to suggest some better options.
Thanks
There won't be any undefined values in the array returned by .split(). You're getting undefined because your print code has hardcoded indexes higher than the highest index in the array.
Sorry, I don't have time right now to test this, or explain it beyond mentioning that .slice() creates a new array extracting a range from the source array, and .join() is (obviously) the opposite of .split(), but maybe you could try something like this:
var wordArray = kstring.split(" ", 50),
i, h, l
wordsPerLine = 5,
lineHeight = 20;
for (i=0, h=0, l=wordArray.length; i < l; i+=wordsPerLine, h+=lineHeight) {
ctx.fillText( wordArray.slice(i, Math.min(l, i+wordsPerLine)).join(" "),
leftOffset, txtHeight + h);
}

Categories