This is from chapter 6 in Eloquent Javascript:
Code:
function splitParagraph(text) {
var fragments = [];
while( text != "" ) // ?
if (text.charAt(0) == "*") {
fragments.push({type: "emphasized"});
etc...
I am having trouble grasping what the while loop is doing. Text is a string. Does the while loop read "while text doesn't have any characters remaining.." Is the while loop looking at every character in the string one by one making sure there is another character left?
The while loop keeps running while the condition inside is true. In this case, text != "" is true if the string in question is not an empty string.
In this particular case, I guess text must be changed somewhere inside the loop, otherwise it doesn't make sense to use a while construct here.
NOTE: Actually, in JavaScript, the != and == operators will evaluate in a pretty curious way: 0, [] and "", for instance, will all be considered equal:
"" != [] -> false
0 != [] -> false
0 != "" -> false
=== and !== can be used to enforce strict equality.
It checks if text isn't an empty string (length 0 and containing no characters).
"Is the while loop looking at every character in the string
one by one making sure there is another character left?"
Yes though the entire loop is not shown that is almost certainly what is being done.
The while condition checks if the text string is empty.
If not empty, the loop iterates through the body of the loop.
The text.charAt(0) checks the first character of the string. If a '*' character is found,
an element is added to the fragments array.
Within the body there will be code to remove the first character of the text string
and the loop then processes the next character of the string.
while( text != "" )
if (text.charAt(0) == "*") {
fragments.push({type: "emphasized"});
What does text != “” mean?
It means if the value of text can not be coerced to match ""
consider this code
if ("abc" != "") {
console.log("1 ok");
}
if ([] != "") {
console.log("2 ok");
}
if (0 != "") {
console.log("3 ok");
}
if (false != "") {
console.log("4 ok");
}
on jsfiddle
Oh dear, what happened in case 2 and 3 and 4?
Related
i want to validate a password field with the following conditions:
One uppercase character
One lowercase character
One number
One special character
Eight characters minimum
If the password input is correct i want to make the pass field green if not it should be red.
I tried with this code but doesnt work:
let password = document.querySelectorAll(".control-group")[3];
password.addEventListener("focusout", () => {
let inp = password.value;
if (
inp.match(/[a-z]/g) &&
inp.match(/[A-Z]/g) &&
inp.match(/[0-9]/g) &&
inp.match(/[^a-zA-Z\d]/g) &&
inp.length >= 8
) {
password.style.backgroundColor = "green";
} else {
password.style.backgroundColor = "red";
}
});
The code you provided is not working due to the fact that
inp.match(/[a-z]/g) && inp.match(/[^a-zA-Z\d]/g)
is just "false". You are telling there "if it contains alphabetic characters as well as it doesn't contains any", which is some sort of
let i = 0;
if (i == 1) {...}
As I said on one of the comments of your question, just search for another solution, like the one that #harsh-saini said.
Output of match() is not true or false, but the match thing like str or int or if it wrong it will show null. So in your case better use "if your case (if input.match() != null) as true". There is the example !
var input = "GoodMorning Sir"
if (input.match(/[0-9]/g) != null){
console.log("there are number here")
} else if (input.match(/[A-Z]/g) != null){
console.log("there are uppercase here")
}
//this is your if else code, try to console.log your condition
//as you can see it wont giving output true or false
console.log(input.match(/[A-Z]/g)) // ["G", "M" , "S"]
A group of me and two other people are working to make a Jeopardy game (themed around United States History questions) all in JavaScript. For our final Jeopardy screen, the two teams will each bet a certain amount of money. To prevent a team from typing in random letters for a bet (i.e typing in "hasdfhgasf" instead of an actual amount), we're trying to write an 'onEvent' command that checks to see if a bet is null. If that bet is null, then the code should come up with a message on the screen that tells them to check their bets again.
We tried using statements like, if "null" or if " " but neither of these statements works. We've worked with using getNumber and getText commands, along with just regular variable comparisons with or booleans. So far, we haven't had any luck with these methods.
Here's the group of code we're having issues with:
onEvent("finalJeopardyBetSubmit", "click", function() {
team1Bet = getNumber("team1BetInput");
team2Bet = getNumber("team2BetInput");
console.log(team1Bet);
console.log(team2Bet);
if (getText("team1BetInput") == "" || getText("team2BetInput") == "") {
console.log("Check bet!");
finalJeopardyError();
} else if ((getText("team1BetInput") != 0 || getText("team2BetInput") != 0)) {
console.log("Check bet!");
finalJeopardyError();
} else if ((getNumber("team1BetInput") < 0 || getNumber("team2BetInput") < 0)) {
console.log("Check bet!");
finalJeopardyError();
} else if ((getNumber("team1BetInput") > team1Money || getNumber("team2BetInput") > team2Money)) {
console.log("Check bet!");
finalJeopardyError();
} else {
console.log("Done");
}
});
You can also check out the whole program on Code.org if you'd like to get a better look.
We expect that with the console.log commands, it should say "check bet" if the bets return as null. Instead, the code has ended up fine, and not displaying our error message, even if we type in nothing or just random letters.
a null variable will evaluate to false. Try:
if(variable){
// variable not null
}else{
// variable null
}
Convert the value to a Number first using Number(value) and then check for falsy values using the logical not ! operator. If they enter alphabetic characters, then calling Number('abc') results in NaN.
If a value can be converted to true, the value is so-called truthy. If
a value can be converted to false, the value is so-called falsy.
Examples of expressions that can be converted to false are:
null; NaN; 0; empty string ("" or '' or ``); undefined.
The ! will change any of the falsy values above to true, so you can check for all of them with just the first if statement below.
onEvent("finalJeopardyBetSubmit", "click", function() {
// Convert these values to numbers first
var team1Bet = Number(getNumber("team1BetInput"));
var team2Bet = Number(getNumber("team2BetInput"));
if (!team1Bet || !team2Bet) {
// Handle invalid number error
}
else if (team1Bet < 0 || team2Bet < 0) {
// Handle invalid range error
}
else if (team1Bet > team1Money || team2Bet > team2Money) {
// Handle insufficient funds error
}
else {
// Finish game
}
})
You can read more about the logical operators here.
I am writing one small function which validates one text, and I am very upset because of the validation.
The problem is: when I try to compare the string to null (to check the cancel button), it works depending on where I put the condition! It seems to be working only when I put at the beginning of the validation. I have tested it with parenthesis for each condition too, but I get the same result.
What´s happening here?
I found this answer on Stack Overflow, but it is for Python and I don´t understand it very well:
Does the Order of Conditions affect Performance?
Code
function validate()
{
var isValid = false;
var text;
while (isValid == false)
{
text = prompt("Enter one text between 1 and 10 characters, no empty, blank spaces, only numbers");
/*
WITH NULL (CANCEL BUTTON) VALIDATION AT THE BEGINNING,
IT WORKS:
*/
if (text != null &&
(text.length >= 1 && text.length <= 10) &&
text != "" &&
isNaN(text) == false)
{
isValid=true;
}
/*
WITH NULL (CANCEL BUTTON) VALIDATION AT ANOTHER POSITION, IT DOESN´T WORK:
It generates "TypeError:Text is null"
*/
if ( (text.length >= 1 && text.length < 10) &&
isNaN(text) == false && text != "" && text !=null)
{
isValid = true;
}
}
if (isValid == true)
{
// Some code when validation is OK
}
}
You want to check if the text is not null first, because if that condition fails, the rest of the conditions will not be evaluated, since the && invariant has been violated. If the text is null, and the null check comes after some other check, you will receive an error.
Because let's say that we had the following values:
var text = 'Tim is an alright person',
notText = null
If we try to access a property of notText, we will get an error because null doesn't have a properties like length. So, in code:
if(text.length){...}
works because text has a length property. However, the following does not work:
if(notText.length){...}
because notText does not have a length property. It will throw the error of TypeError because you are trying to do something with the null type that is not allowed.
So, we need the text != null check first because it will fail early, before trying the other expressions.
In simple words:
If you evaluate text.anyproperty == null you're asking if the anyproperty of the var text is null, but this way you are taking for granted that text is not null, which will fail with the error you mentioned (TypeError) if text is actually null.
In order to avoid this pitfall you must ask first for text and then for text.anyproperty like this: if(text != null && text.anyproperty != null) ... so, this way, if text != null fails, the text.anyproperty != null will not be evaluated and you won't get the TypeError.
For the purpose of your validation, using if(text != null && text.anyproperty != null) you can achieve your goal, since if text is null, it doesn't make any sense check text.anyproperty (that's why the rest of the expression, the code after &&, is not evaluated).
Hope this help you understand better this matter :)
I want make a if statement with a String input.
I have a MongoDB with Achievement data. This data contains a string with the condition that has to be met to get the achievement.
I want to use the condition (in String format) as the condition in an if statement.
I have the following code:
function checker(condition, achievementId, doc) {
if((condition) && doc.Achievement.indexOf(achievementId) == -1) {
return true
} else {
return false
}
The doc is the data object that will get unlock the achievement.
makes sure the achievement isn't already unlocked.
doc.Achievement.indexOf(achievementId) == -1
Example condition in the if statement:
var condition = "doc.Score == 100"
Javascript will allow this code but will always return true. Is it possible to make JS read the String as a if statement?
Your only choice to accomplish that is the use of eval(), which pretty much does what it says. It evaluates a string of code.
if(eval(condition) && doc.Achievement.indexOf(achievementId) == -1) {
}
I have a field that needs to accept input values for city/state in several formats, including City ST (Chicago IL), City, ST (Chicago, IL), and City,ST (Chicago,IL - no space between). We're testing for a two-letter state code after either a comma or the last instance of a space (because city names can have spaces.)
I have the following code that fails values that should pass, and vice versa.
var x = "Chicago,IL";
if (
(isNaN(x) && x.indexOf(' ') < 0 && x.split(" ").pop().length > 2) ||
(isNaN(x) && x.indexOf(',') > 0 && x.split(",").pop().trim().length > 2)
) {
alert("fail");
}
else {
alert("pass");
}
(Fiddle here)
So what my code SHOULD do is fail if 1) the value is not a number AND contains at least one space AND there are more than 2 characters after the final space, or 2) the value is not a number AND it contains a comma AND there are more than 2 characters after the comma (I'm trimming out a potential space after the comma.)
What's actually happening is, it's passing these values:
Chicago IL
Chicago, IL (with a space, even though it's trimming the space)
But failing Chicago,IL (entered initially without a space.) The reason I think it's a problem with the OR (II) is that if I remove the first part and test only for the value containing a comma, Chicago,IL passes. I thought that OR conditionals only return false if both sides of the OR are false, but that doesn't seem to be the case here.
I'm sure this is a really simple thing, but I've been staring at it for way too long and just can't see it.
That seems too complicated. If you are going to do it like that, use multiple statements (so that they can be reasoned about easier). Anyway, here is my "solution" which, admittedly, does not try to address why the original didn't work as expected:
var cityState = /^\w+(?:,\s*|\s+)\w{2}$/;
if (cityState.test(input)) {
// good
}
To accept either "City Name, State" or "City Name State", consider this (more complex) regular expression. The key to this working is the lazy modifier and the anchoring.
function isValidState (st) {
// This could be turned into an appropriate whitelist, and may include
// things like "Illinois".
return st.length == 2;
}
function parseCityState (cs) {
var match = cs.match(/^\s*(\w.*?)\s*([, ])\s*(\w+)\s*$/) || [];
var city = match[1];
var commaUsed = match[2] == ',';
var state = match[3];
if (city && state && isValidState(state)) {
return {city: city, state: state, commaUse: commaUsed}
} else {
return undefined;
}
}
Now, if you're interesting in why the original fails, consider this updated analysis for why "Chicago, IL" fails. Let x = "Chicago, IL", then:
isNaN(x) -> true
x.indexOf(' ') -> >0
x.indexOf(',') -> >0
x.split(' ') -> ["Chicago,", "IL"]
x.split(',') -> ["Chicago", " IL"]
And substituting:
true && (>0 < 0) && ["Chicago,", "IL"].pop().length > 2
||
true && (>0 > 0) && ["Chicago", " IL"].pop().trim().length > 2
Evaluation, again (note that the test for "no space" fails the first expression line because there is a space):
true && false && "IL".length > 2
||
true && true && "IL".length > 2
And evaluation again (note that both expression lines fail because "IL" only has a length of 2):
true && false && false
||
true && true && false
And ultimately this rejects the input:
false || false -> false
This is true:
I thought that OR conditionals only return false if both sides of the
OR are false
About this:
if I remove the first part and test only for the value containing a comma, Chicago,IL passes
In your fiddler example, commenting out the first test prints "fail", which implies that it is evaluating to true.
There is no problem with JS ORs. But what is what you were expecting?
I think you have a mistake on this line
x.indexOf(' ') < 0
should be
x.indexOf(' ') > 0
But if I were you, I'd use a regular expression:
var info = 'South Beach, FL';
var regex = /\w+(\w+ \w+)*\s*,\s*[a-zA-Z]{2}/;
alert(regex.test(info) ? 'Valid' : 'Invalid')