Using typeof operator in JS correctly? - javascript

I am making a simple hangman game in JavaScript. I'm playing around trying to add new features and one of the features I'd like to add is to check the input the user gives (when they guess a letter of the unknown word) to make sure it is in fact an alphanumeric input (or my intention is to check that the input isn't a symbol like "!" or a number like "5").
I know I could probably use a global variable that contains all the valid characters and check the input against those characters but I was wondering if there is a built in method for this. I found the typeof operator but it seems that the types of characters I'm checking for get converted to strings by JavaScript.
The loop in which I'm trying to implement this:
while (remainingLetters > 0 && numberOfGuesses > 0) {
alert(answerArray.join(" "));
alert("You have " + numberOfGuesses + " guesses remaining.");
var guess = prompt("Guess a letter, or click \
'Cancel' to stop playing.").toLowerCase();
if (guess === null) {
break;
} else if (typeof guess === "number") {
alert("Please enter a single LETTER.");
} else if (guess.length !== 1) {
alert("Please enter a single letter.");
} else {
for (var j = 0; j < word.length; j++) {
if (word[j] === guess) {
answerArray[j] = guess;
remainingLetters--;
// there is some code missing here that I'm pretty sure is not essential
// to my question!
When I run that in Chrome's dev tools, I can input "2" and it never gives me the alert I'm looking for - it doesn't crash or anything it just re-starts the loop (which is the status quo before I tried to implement this "feature").
Thanks in advance!

The issue with this code is that prompt always returns a string value. These values may or may not be able to be converted to a Number; this conversion would be performed using parseInt or parseFloat. (If the string can be converted to a numerical value, these methods return that value; otherwise, they return NaN.) However, typeof performs no interpolation—it states the type of the variable as it exists, and not any types to which it could potentially be converted. Therefore, typeof guess will always evaluate to string. To check if a string contains a numerical value, you could use the condition if (!isNaN(parseInt(guess)) or if (!isNaN(parseFloat(guess)) (note that the isNaN method must be used instead of a traditional equality check).
However, you might want to structure your checks around ensuring that the entry is a letter rather than accounting for the myriad ways in which it might not be. For instance, # and ≥ are not numbers, but they are also not letters. Similarly, if your answerArray contains only Latin letters without diacritics, you might want to disallow guesses of characters like é and ç. Thus, consider using RegEx to check if the guessed string contains an acceptable letter. As in this Stack Overflow post, you can use the following if statement to ensure that the string is one character long and is a valid letter: if (str.length === 1 && str.match(/[a-z]/)). You can refer to that post for ways of addressing more complicated character sets (e.g., non-Latin letters or those with diacritics).

Related

REGEX to match only VALID EXCEL COLUMNS (A-XFD)

Ok, I have ANOTHER REGEX question for everyone.
I have a field that has multiple validation steps. The first step is to ensure it isn't blank, second is to ensure that only between 1 and 3 CAPITAL LETTERS are entered, and third, to ensure it doesn't contain "[" (an opening bracket will denote a function in this scenario and we skip validation). All of this works. Now, I have to ensure that the value being entered is only a valid Excel Column Reference. Valid Excel Columns can be the letters A - XFD.
I am currently using:
if (checkValue !==""){ //check for not blank
if ((checkValue.match(/^[A-Z]{1,3}$/) === null) && (functionCheck === false) && (validateColumnRange(rangeFrom))) { //check for only 1 - 3 alpha chars & run function check (function looks for "["), and run function check to validate column range
//do A - XFD validation here
}
}
any further direction will be much appreciated as I have been through regex tuts for hours now and am lost.
I had been given help on a similar issue in the past and my poor attempt to emulate the function that was provided then is as follows:
function validateColumnRange(valueRange) {
if (typeof valueRange !== "string" || !valueRange.length)
return false;
var startIndex = valueRange.search(/[\d+]/);
var column = valueRange.substring(0, startIndex).toUpperCase();
return (column >= "A" && column <= "XFD");
}
it doesn't work...please help
Since you've already determined that the value is 1-3 alphabetic characters, how about:
(column.length < 3 || column <= "XFD")
Any value with 2 or less letters should be acceptable, and for the case of three letters, alphabetic comparison is adequate.
Use this regex expression:
/^[A-XFD]+$/

JavaScript praseInt("3e3", 10) gives answer 3

My task to prompt for a number. And loop till its a number
do {
num=prompt ("Please enter a number:");
if (parseInt(num,10)) {
if (typeof num !=="number") {
if (!isNaN(num)) {
stop=1;
}
}
}
} while (stop != 1);
When I enter "3e3" it works. Y?
how do i fix the praseInt("3e3", 10)?
Check it with regular expression such as /^\d+$/.
if (/^\d+$/.test(num)) {
// it's an integer
} else {
// it's not an integer
}
parseInt will take the first characters of the string until it finds one that it's numeric (or reaches the end).
With that in mind, 3e3 reads the first 3 and discards the rest.
That said, your logic is flawed: parseInt returns the number, whereas you seem to be treating it like it were changing it.
That's because parseInt ignores anything after (and including) first invalid character (step 11.)
If you want to reject things like 3e3, then you can simply test whether the string contains decimals only by doing /^\s*\d+\s*$/.test(num).
If you want to process things like 3e3, then you can simply use unary + operator to convert a string to a number, something like +num. (This will accept strings like 4.2e+42 or 0x2A.)

Calculate real length of a string, like we do with the caret

What I want is to calculate how much time the caret will move from the beginning till the end of the string.
Explanations:
Look this string "" in this fiddle: http://jsfiddle.net/RFuQ3/
If you put the caret before the first quote then push the right arrow ► you will push 3 times to arrive after the second quote (instead of 2 times for an empty string).
The first way, and the easiest to calculate the length of a string is <string>.length.
But here, it returns 2.
The second way, from JavaScript Get real length of a string (without entities) gives 2 too.
How can I get 1?
1-I thought to a way to put the string in a text input, and then do a while loop with a try{setCaret}catch(){}
2-It's just for fun
The character in your question "󠀁" is the
Unicode Character 'LANGUAGE TAG' (U+E0001).
From the following Stack Overflow questions,
" Expressing UTF-16 unicode characters in JavaScript"
" How can I tell if a string contains multibyte characters in Javascript?"
we learn that
JavaScript strings are UCS-2 encoded but can represent Unicode code points outside the Basic Multilingual Pane (U+0000-U+D7FF and U+E000-U+FFFF) using two 16 bit numbers (a UTF-16 surrogate pair), the first of which must be in the range U+D800-U+DFFF.
The UTF-16 surrogate pair representing "󠀁" is U+DB40 and U+DC01. In decimal U+DB40 is 56128, and U+DC01 is 56321.
console.log("󠀁".length); // 2
console.log("󠀁".charCodeAt(0)); // 56128
console.log("󠀁".charCodeAt(1)); // 56321
console.log("\uDB40\uDC01" === "󠀁"); // true
console.log(String.fromCharCode(0xDB40, 0xDC01) === "󠀁"); // true
Adapting the code from https://stackoverflow.com/a/4885062/788324, we just need to count the number of code points to arrive at the correct answer:
var getNumCodePoints = function(str) {
var numCodePoints = 0;
for (var i = 0; i < str.length; i++) {
var charCode = str.charCodeAt(i);
if ((charCode & 0xF800) == 0xD800) {
i++;
}
numCodePoints++;
}
return numCodePoints;
};
console.log(getNumCodePoints("󠀁")); // 1
jsFiddle Demo
function realLength(str) {
var i = 1;
while (str.substring(i,i+1) != "") i++;
return (i-1);
}
Didn't try the code, but it should work I think.
Javascript doesn't really support unicode.
You can try
yourstring.replace(/[\uD800-\uDFFF]{2}/g, "0").length
for what it's worth

JavaScript variable less than 4 characters

I have "name" JavaScript variable. If variable "name" contains less than 4 characters I want to execute line: msg('name','Your name must contain minimum 4 characters.')';
I have tried something like this but it interpretated mathematical. Any idea? Thank you.
if(name < 4 ) {
msg('name','Your name must contain minimum 4 characters.');
return false;
}
if (name.length < 4) {
...
}
You probably want to check the length of the string, not the numeric value of the string itself:
if(name.length < 4) {
// ...
if(name.length < 4) {
//Do something
}
You have to check the length of the variable.
length can also be used to check the length of an Array
\n (new line) is also counted as a character.
Depending on your definition of “character”, all answers posted so far are incorrect. The string.length answer is only reliable when you’re certain that only BMP Unicode symbols will be entered. For example, 'a'.length == 1, as you’d expect.
However, for supplementary (non-BMP) symbols, things are a bit different. For example, '𝌆'.length == 2, even though there’s only one Unicode symbol there. This is because JavaScript exposes UCS-2 code units as “characters”.
Luckily, it’s still possible to count the number of Unicode symbols in a JavaScript string through some hackery. You could use Punycode.js’s utility functions to convert between UCS-2 strings and UTF-16 code points for this:
// `String.length` replacement that only counts full Unicode characters
punycode.ucs2.decode('a').length; // 1
punycode.ucs2.decode('𝌆').length; // 1 (note that `'𝌆'.length == 2`!)

Compare phone numbers in JavaScript

I have an array of phone numbers and I need to find if a particular phone number is in it.
What I tried doing at first was if(arr.indexOf(phoneNumber) != -1) { bla.. }. And it worked - sometimes.
I later discovered that since the number/s would arrive from different phones/entry forms, some people use country codes (like +1-xxx-xxx-xxxx), some wouldn't. Some use spaces as seperators and some just put in 10 digits in a row. In short - hell to compare.
What I need is an elegant solution that would allow me to compare, hopefully without having to replicate or change the original array.
In C++ you can define comparison operators. I envision my solution as something like this pseudo-code, hopefully using some smart regex:
function phoneNumberCompare(a, b) {
a = removeAllSeperators(a); //regex??
a = a.substring(a.length, a.length - 10);
b = removeAllSeperators(b); //regex??
b = b.substring(b.length, b.length - 10);
return (a < b ? -1 : (a == b ? 0 : 1)); //comaprison in C++ returns -1, 0, 1
}
and use it like if(arr.indexOf(phoneNumber, phoneNumberCompare) != -1)
Now, I know a solution like this construct does not exist in JavaScript, but can someone suggest something short and elegant that achieves the desired result?
As always, thanks for your time.
PS: I know indexOf() already has a second parameter (position), the above is just ment to illustrate what I need.
You really should sanitize all the data, both at collection and in the DB.
But for now, here's what you asked for:
function bPhoneNumberInArray (targetNum, numArray) {
var targSanitized = targetNum.replace (/[^\d]/g, "")
.replace (/^.*(\d{10})$/, "$1");
//--- Choose a character that is unlikely to ever be in a valid entry.
var arraySanitized = numArray.join ('Á').replace (/[^\dÁ]/g, "") + 'Á';
//--- Only matches numbers that END with the target 10 digits.
return (new RegExp (targSanitized + 'Á') ).test (arraySanitized);
}
How it works:
The first statement removes everything but digits (0-9) from the target number and then strips out anything before the last 10 digits.
Then we convert the array to be searched into a string (very fast operation).
When joining the array, we use some character to separate each entry.
It must be a character that we are reasonably sure would never appear in the array. In this case we chose Á. It could be anything that doesn't ever appear in the array.
So, an array: [11, 22, 33] becomes a string: 11Á22Á33Á, for example.
The final regex, then searches for the target number immediately followed by our marker-character -- which signals the end of each entry. This ensures that only the last 10 digits of an array's number are checked against the 10-digit target.
Testing:
var numArray = ['0132456789', "+14568794324", "123-456-7890"];
bPhoneNumberInArray ("+1-456-879-4324", numArray) // true
bPhoneNumberInArray ("+14568794324", numArray) // true
bPhoneNumberInArray ("4568794324", numArray) // true
bPhoneNumberInArray ("+145 XXX !! 68794324", numArray) // true !
bPhoneNumberInArray ("+1-666-879-4324", numArray) // false
You should sanitize both the input and all array values, to make sure they conform to the same ruleset.
Just create a function called sanitizePhonenumber, where you strip (or add, depending on your preferences) the country code and all other signs you dont want there.
After that you can just compare them as you are doing now.

Categories

Resources