I need your advice (I'm a beginner in JS).This is my code:
function fn(pin) {
if (pin.length === 4 && !isNaN(pin) && pin % parseInt(pin) === 0 && Number(pin) > 0) {
return true;
}
return false
}
console.log(fn("123a.78")) // false
So i check the length, that it is a number, that it is integer and that it is bigger than 0.
But how should i write the condition to eliminate strings of this type: "12.0" (because it also has length of 4 and is also integer)? If i try conditions with pin.parseFloat or parseInt, it will affect strings like this type "1234" as well. Or maybe i write them in the wrong way...
I would go with a regular expression to validate the input.
The regular expression to validate 4 digits only would look like this: /^[0-9]{4}$/
Regular expressions have methods that allow them to test if variables are of their type.
For instance:
const pin = '1234';
const pin2 = '12.4'
const regExp = /^[0-9]{4}$/
regExp.test(pin) //returns true
whereas:
regExp.test(pin2) //returns false
You can use this validation as the condition in your if/else conditions to execute the code you need.
freecode tutorial on Regular Expressions
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/#es6
Regular expressions playground:
https://regex101.com/
Related
I store some parameters client-side in HTML and then need to compare them as integers. Unfortunately I have come across a serious bug that I cannot explain. The bug seems to be that my JS reads parameters as strings rather than integers, causing my integer comparisons to fail.
I have generated a small example of the error, which I also can't explain. The following returns 'true' when run:
console.log("2" > "10")
Parse the string into an integer using parseInt:
javascript:alert(parseInt("2", 10)>parseInt("10", 10))
Checking that strings are integers is separate to comparing if one is greater or lesser than another. You should always compare number with number and string with string as the algorithm for dealing with mixed types not easy to remember.
'00100' < '1' // true
as they are both strings so only the first zero of '00100' is compared to '1' and because it's charCode is lower, it evaluates as lower.
However:
'00100' < 1 // false
as the RHS is a number, the LHS is converted to number before the comparision.
A simple integer check is:
function isInt(n) {
return /^[+-]?\d+$/.test(n);
}
It doesn't matter if n is a number or integer, it will be converted to a string before the test.
If you really care about performance, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
return function(n) {
return re.test(n);
}
}());
Noting that numbers like 1.0 will return false. If you want to count such numbers as integers too, then:
var isInt = (function() {
var re = /^[+-]?\d+$/;
var re2 = /\.0+$/;
return function(n) {
return re.test((''+ n).replace(re2,''));
}
}());
Once that test is passed, converting to number for comparison can use a number of methods. I don't like parseInt() because it will truncate floats to make them look like ints, so all the following will be "equal":
parseInt(2.9) == parseInt('002',10) == parseInt('2wewe')
and so on.
Once numbers are tested as integers, you can use the unary + operator to convert them to numbers in the comparision:
if (isInt(a) && isInt(b)) {
if (+a < +b) {
// a and b are integers and a is less than b
}
}
Other methods are:
Number(a); // liked by some because it's clear what is happening
a * 1 // Not really obvious but it works, I don't like it
Comparing Numbers to String Equivalents Without Using parseInt
console.log(Number('2') > Number('10'));
console.log( ('2'/1) > ('10'/1) );
var item = { id: 998 }, id = '998';
var isEqual = (item.id.toString() === id.toString());
isEqual;
use parseInt and compare like below:
javascript:alert(parseInt("2")>parseInt("10"))
Always remember when we compare two strings.
the comparison happens on chacracter basis.
so '2' > '12' is true because the comparison will happen as
'2' > '1' and in alphabetical way '2' is always greater than '1' as unicode.
SO it will comeout true.
I hope this helps.
You can use Number() function also since it converts the object argument to a number that represents the object's value.
Eg: javascript:alert( Number("2") > Number("10"))
+ operator will coerce the string to a number.
console.log( +"2" > +"10" )
The answer is simple. Just divide string by 1.
Examples:
"2" > "10" - true
but
"2"/1 > "10"/1 - false
Also you can check if string value really is number:
!isNaN("1"/1) - true (number)
!isNaN("1a"/1) - false (string)
!isNaN("01"/1) - true (number)
!isNaN(" 1"/1) - true (number)
!isNaN(" 1abc"/1) - false (string)
But
!isNaN(""/1) - true (but string)
Solution
number !== "" && !isNaN(number/1)
The alert() wants to display a string, so it will interpret "2">"10" as a string.
Use the following:
var greater = parseInt("2") > parseInt("10");
alert("Is greater than? " + greater);
var less = parseInt("2") < parseInt("10");
alert("Is less than? " + less);
I need to validate a crossword clue's enumeration (the number(s) in the brackets). For example, "Big star (3,5)" - the enumeration is 3,5.
I'm struggling with the required regular expression. Rules should be as follows:
only allow characters 0-9, hyphens and commas
each number shouldn't start with a zero e.g. "09" should be just "9"
it should start with a number
it should end with a number
it shouldn't allow repeated hyphens/commas e.g "3,,5" or "3--5" or "3,-5" or 3-,5"
Some VALID examples...
1
1,2
1,2-3
1,2-3,4
Some INVALID examples...
text
-1
1,
1,,2
0-1
3-04
Hopefully you get the idea. Any help would be greatly appreciated.
Regular expressions are very powerful but can be a pain to write out sometimes, especially if you don't use them often. This is why I often use this site to help.
After speaking in the comments, a logic error became apparent: the regexp would not match anything with 0, even if it did not start with it. It would also not match numbers without - like just 10.
Now, I came up with ([1-9]([0-9]+)?(((\-|\,)[1-9]([0-9]+)?)+)?) but there was another problem:
10-5-40 would be matched as expected
but the 3-2 in 03-2 and the 3 and 2 in 03-02 would also be matched.
So I included some JS logic in addition to the RegExp. Hopefully now it works as intended.
let Regexp1 = /([1-9]([0-9]+)?(((\-|\,)[1-9]([0-9]+)?)+)?)/;
let Regexp2 = /([1-9]([0-9]+)?(((\-|\,)[1-9]([0-9]+)?)+))/;
function test(t) {
match1 = (t.match(Regexp1) != null);
match2 = (t.match(Regexp2) != null);
let matches = false;
if(match1 && match2) {
matches = true;
} else if(match1 && !match2) {
if(t.match(Regexp1)[0].length == t.length) {
matches = true;
} else {
matches = false;
}
}
if(t.match(Regexp1)[0].length != t.length) {
matches = false;
}
console.log(matches);
return matches;
}
test("10-5"); // true
test("03-4"); // false
test("0-5"); // false
test("1,05"); // false
test("1--5"); // false
test("10"); // true
test("10-05"); // false
So to check if a string is a positive integer, I have done some research and found this solution here by someone:
Validate that a string is a positive integer
function isNormalInteger(str) {
return /^\+?(0|[1-9]\d*)$/.test(str);
}
However, I put this into test, and found that numbers with pure 0's on the decimal places does not seem to be working. For example:
15 ===> Works!
15.0 ====> Does not work :(
15.000 ===> Does not work :(
Build upon the existing method, how could I allow pure-0's on the decimal places and make them all work? Please note 15.38 should not work, but 15.00 should.
No need to use regex here.
function isNormalInteger(str) {
var n = parseInt(str);
return n > 0 && n == +str;
}
Then test it:
isNormalInteger(15)
true
isNormalInteger(15.00)
true
isNormalInteger(15.38)
false
isNormalInteger(-15)
false
isNormalInteger(-15.1)
false
First of all the function should be called isNormalNumber instead of isNormalInteger as it accepts decimals, then this is the REgex you need:
function isNormalNumber(str) {
return /^\+*[0-9]\d*(\.0+)?$/.test(str);
}
alert(isNormalNumber("+10.0") + "::" + isNormalNumber("+10.9") + "::" + isNormalNumber("10"));
Returns true::false:true.
EDIT:
This is an edit to avoid matching leading zeros like in the numbers 001234 and 07878:
^\+*[1-9]\d*(\.0+)?$|^0(\.0+)?$
Quick and dirty
function isNormalInteger(str) {
var ival=parseInt(str);
return ival!=NaN && ival>=0 && ival==parseFloat(str);
}
Thanks to some of the answers on this site, I built a function to validate an integer inside a prompt in javascript. I found out how to use isNaN and the result of % in order to meet my needs, but there must be something wrong, because is still not working: This function for validation needs to accept only integers, and as extra bonus, it will also accept a special keyword used for a different purpose later on in the program.
So, previously I had defined:
var value = prompt("Type an integer");
So after that, I made a call for the validation function, and that included three conditions: The validation warning would jump if:
1) The string is not a number
2) The string % 1 is not 0 (means is not an integer)
3) The string is not the special keyword ("extra") which is also valid as input.
The function needs to loop and keep showing the prompt until a valid data is written.
while (isNaN(value) == true && value % 1 != 0 && value != "extra") {
alert("Please, type an integer");
var value = prompt("Type an integer");
}
What am I doing wrong? Thank you so much for any ideas. I know the integer validation has been asked many times here, and here I got a few ideas, but I might be missing something...
You might be complicating things too much... A quick regular expression will do the trick.
while (!/^(\d+|extra)$/i.test(value)) {
...
}
You typed only one equal at
isNaN(value) = true
jsFiddle example
var int = 10;
var str = "10";
var isInt = function(value) {
return (str === 'extra' || !isNaN(parseInt(value, 16)) || /^\d+$/.test(value));
};
var isIntStrict = function(value) {
return (isInt(value) && typeof value !== 'string');
}
console.log('false', isInt('kirk'));
console.log('true', isInt(int));
console.log('true', isInt(str));
console.log('true', 'strict - int', isIntStrict(int));
console.log('false','strict - string', isIntStrict(str));
console.log('false','strict - string', isIntStrict('0x04'));
console.log('true','strict - string', isIntStrict(0x04));
I assume that for your purposes #elclanrs' answer is all you need here, and is the simplest and most straightforward, but just for completeness and dubious laughs, I'm pretty sure that the following would also do what you're looking for:
function isAnIntOrExtra(v) {
if (parseInt(+v) === +v && v !== '') {
return parseInt(+v);
}
else if (v === 'extra') {
return v;
}
else {
return false;
}
}
Fiddle here
These should all pass and return an integer in decimal notation:
'387' returns 387
'-4' returns -4
'0' returns 0
'2.4e3' returns 2400
'0xf4' returns 244
while these should all fail:
'4.5' returns false
'2.4e-3' returns false
'0xgc' returns false
'' returns false
'seven' returns false
And the magic-word 'extra' returns 'extra'
Of course, it'll "fail" miserably with values like '1,345', and will probably roll right over octal notation, treating it as though it were decimal notation (depending on the JavaScript engine?), but it could be tweaked to handle those situations as well, but really, you're better off with the regex.
I have this following if statement:
RG is "100" and max is "85"
if (RG == "" | RG > max) {
//Doesn't execute
}
Since RG isn't "" and RG is larger than max why isn't the code executing? I believed the operator was short circuiting (hence only the one pipe |) but changing it didn't make any difference. My guess is that it is comparing literal strings - so how do I force javascript to treat them as floats?
Just to be clear I need both parts of the OR to be checked and only execute if either of them is true.
I believed the operator was short circuiting (hence only the one pipe |) but changing it didn't make any difference
I take it then it originally looked like this:
if (RG == "" || RG > max) {
//Doesn't execute
}
We can ignore the first part because it's false, so your question is why wasn't RG > max true? And the answer is that "100" comes before "85" in the string collation order. Strings are not numbers, you don't compare them numerically.
If you want them to be floats as you said, you can make them numbers via parseFloat (or parseInt as they look like integers, but you said floats, so...):
if (RG == "" || parseFloat(RG) > parseFloat(max)) {
//Doesn't execute
}
I've done it inline there, but the odds seem high you'll want to do it earlier and assign the result to variables, unless this really is the only place you'll use the values as numbers.
if (RG === "" || parseFloat(RG) > parseFloat(max)) {
// should execute
}
i prefer
if((!RG) || RG*1>max*1)
{
...
}
How do I force javascript to treat them as floats?
Like this:
var RG = "100",
max = "85";
if (RG === "" || Number(RG) > Number(max)) {
// Your code goes here.
// It will be executed if RG is the empty string OR if RG > max.
}
Number(foo) will coerce foo into a number. You could also use +foo but I think this is more readable.
You should use parseFloat instead if the string can contain text as well.
Note that you need a strict equality check (===) when checking for the empty string, since RG == "" will be true if RG is 0, '0', false, etc. as well.
well, parse the strings.
if (RG == "" | parseFloat(RG) > parseFloat(max)) {
//Do Something }