Switch-Case for strings in Javascript not working as expected - javascript

So I have this problem with strings and switch-case, and I'll try to keep it as simple as possible.
Here event.keyCode has the value "65", and is the result of a keydown event of 'a' (using JQuery).
if (event.keyCode == "65") {
alert("hmmmm");
}
That works, but:
switch (event.keyCode) {
case '65':
alert("Yay!");
break;
}
That doesn't. However this will work:
switch ('65') {
case '65':
alert("Yay!");
break;
}
And if I do this:
var t = '65';
switch (t) {
case '65':
alert("Yay!");
break;
}
It works. And then I tried this:
var t = event.keyCode;
switch (t) {
case '65':
alert("Yay!");
break;
}
But it fails!
So why does it match in the if-block at the beginning, but not for the switch-case?

keyCode is an integer, not a string. When you use ==, the conversion is done implicitly. However, the switch uses the equivalent of ===, which doesn't allow implicit conversions. You can test this easily with:
switch (65) {
case '65':
alert("Yay!");
break;
}
As expected, it does not alert.
This is stated in ECMAScript, 5th edition section 12.11 (switch statement). The interpreter will enter a case statement if "input is equal to clauseSelector as defined by the === operator". input is 65 (integer) and clauseSelector is '65' (string) in my above example, which are not ===.

Related

How to write case in Switch else statement in javavscript?

//This is my Problem
Complete the getLetter(s) function in the editor. It has one parameter: a string, , consisting of lowercase English alphabetic letters (i.e., a through z). It must return A, B, C, or D depending on the following criteria:
If the first character in string is in the set {aeiou}, then return A.
If the first character in string is in the set {bcdfg}, then return B.
If the first character in string is in the set {hjklm},, then return C.
If the first character in string is in the set {npqrstvwxyz}, then return D.
I am trying to implement the above scenarion and to dthis I have written the following code.
//Here is my code
function getLetter(s) {
let letter;
// Write your code here
switch (s) {
case s.match(/[aeiou]/g).includes(s[0]):
letter = 'A'
break;
case s.match(/[bcdfg]/g).includes(s[0]):
letter = 'B'
break;
case s.match(/[hjklm]/g).includes(s[0]):
letter = 'C';
break;
case s.match(/[npqrstvwxyz]/g).includes(s[0]):
letter = 'D';
break;
default:
console.log("hello")
}
return letter
}
The code is showing error. Would any help me to figure it out? How can I implement the above task using switch statement.
I don't know that much switch case, but maybe you can use parenthesis for the switch statement and if "s.match(/[aeiou]/g).includes(s[0])" return true or false
And you forgot ";" after the two first assignment
the way you wrote the switch case may be partially correct in GoLang. but in Javascript, it is not possible to achieve this using Switch-Case statement.
Better try using if-else-if statement something like below
if(s.test(/^[aeiou]/)) {
return 'A';
} else if(s.test(/^[bcdfg]/)) {
return 'B'
}
Check out this: Switch statement for string matching in JavaScript. The issue is that match returns null, which breaks the switch statement.
Use
switch(s){
case str.match(/^xyz/)?.input:
//code
break;
This stops the match from returning null.
Based on how you're using this, you actually want to switch (true) and not switch (s)
i.e. when you have a case y in a switch (x), the test being done is x === y; so you want to do true === some.test()
const s = 'a';
switch (true) {
case /a/.test(s):
console.log('first match');
break;
case /b/.test(s):
console.log('second match');
break;
default:
console.log('no match');
break;
}
Will log first match because
/a/.test('a') is true
and true /* from switch */ === true /* from case test */
Note that in most cases switch can also be written as if..else if..else.
Base your decision on which to use by which is the most readable (err on the side of if patterns)
The above example written as an if might look like this
const s = 'a';
if (/a/.test(s)) {
console.log('first match');
} else if (/b/.test(s)) {
console.log('second match');
} else {
console.log('no match');
}

Switch Case statement for Regex matching in JavaScript

So I have a bunch of regexes and I try to see if they match with another string using this If statement:
if (samplestring.match(regex1)) {
console.log("regex1");
} else if (samplestring.match(regex2)) {
console.log("regex2");
} else if (samplestring.match(regex3)) {
console.log("regex3");
}
But as soon as I need to use more regexes this gets quite ugly so I want to use a switch case statement like this:
switch(samplestring) {
case samplestring.match(regex1): console.log("regex1");
case samplestring.match(regex2): console.log("regex2");
case samplestring.match(regex3): console.log("regex3");
}
The problem is it doesn't work like I did it in the example above.
Any Ideas on how it could work like that?
You need to use a different check, not with String#match, that returns an array or null which is not usable with strict comparison like in a switch statement.
You may use RegExp#test and check with true:
var regex1 = /a/,
regex2 = /b/,
regex3 = /c/,
samplestring = 'b';
switch (true) {
case regex1.test(samplestring):
console.log("regex1");
break;
case regex2.test(samplestring):
console.log("regex2");
break;
case regex3.test(samplestring):
console.log("regex3");
break;
}
You can use "not null":
switch(samplestring){
case !!samplestring.match(regex1): console.log("regex1");
case !!samplestring.match(regex2): console.log("regex2");
case !!samplestring.match(regex3): console.log("regex3");
}

(JavaScript) Using a switch statement with an input box

New to JavaScript so please forgive me if this has an obvious answer. I'm trying to get a switch statement to output a specific phrase depending on the value of an input box, however it will only output the default option. What have I done wrong? Thanks.
<input id="inputIQ" type="number"/>
<button onclick="inputIQFunction()">Submit</button>
<script>
function inputIQFunction()
{
var userinput = document.getElementById("inputIQ").value;
switch (userinput) {
case userinput <= 10:
alert("Less than 10");
break;
case userinput > 10:
alert("Greater than 10");
break;
default:
alert("Please input value");
break;
}
}
</script>
Basically, switch doesn't support conditional expressions. It just jumps to the value according to the cases.
If you put true in the switch (true) part, it'll jump to the case whose have true value.
Try like this
switch (true) {
case userinput <= 10:
alert("Less than 10");
break;
case userinput > 10:
alert("Greater than 10");
break;
default:
alert("Please input value");
break;
}
You cannot use logical conditions in your switch statement. It actually compares your userinput to a result of condition (true \ false), which never occurs.
Use conditions instead:
function inputIQFunction() {
function getIQFunctionOutput(inputValue) {
var parsedInput = parseInt(inputValue);
if (Number.isNaN(parsedInput))
return "Please, enter a correct value";
return parsedInput <= 10
? "Less or equal than 10"
: "Greater than 10";
}
var userinput = document.getElementById("inputIQ").value;
var output = getIQFunctionOutput(userinput);
alert(output);
}
<input id="inputIQ" type="number" />
<button onclick="inputIQFunction()">Submit</button>
P.S. You can actually use switch with logical statements this way:
switch (true) {
case userinput <= 10:
break;
case userinput > 10:
break;
}
but I would highly recommend not to use this approach because it makes your code harder to read and maintain.
Try like this:
<input id="inputIQ" type="number"/>
<button onclick="inputIQFunction()">Submit</button>
<script>
function inputIQFunction() {
var userinput = document.getElementById("inputIQ").value;
userinput = parseInt(userinput);
switch (true) {
case userinput <= 10:
alert("Less than 10");
break;
case userinput > 10:
alert("Greater than 10");
break;
default:
alert("Please input value");
break;
}
}
</script>
A switch works by testing the value of the expression in switch(expression) against the values of each case until it finds one that matches.
In your code, the userinput in switch(userInput) is a string, but your two case statements both have a value of either true or false. So you want to use switch(true) - that's how you get a switch to work with arbitrary conditions for each case. In context:
switch(true) {
case userinput <= 10:
alert("Less than 10");
break;
case userinput > 10:
alert("Greater than 10");
break;
default:
alert("Please input value");
break;
}
I know this is an old thread but I'm just starting out on JS (one week in) and this is the simplest thing I could create just so the logic is understood.
Switch appears to work only by true/false when using a user input value.
My script looks like:
<script>
document.getElementById("click").onclick = function () {
var day = document.getElementById("day").value;
switch (true) {
case day == 1:
document.write("Monday");
break;
case day == 2:
document.write("Tuesday");
break;
default:
document.write("Please enter valid number")
}
</script>
Like I said I'm only a week into this but I'm making a small portfolio for myself with these little things that courses may not teach, I'm open to any one wishing to offer me help learning also, hope it helps with understanding the logic.
You are not fulfilling the requirements of 'switch & case'
userinput <= 10:
It means 'true'
because '<=' is a comparison operator. It compares 'userinput' and ’10'(given value) and give you an answer in boolean(i.e. true or false).
But, here in switch case you need an integer value.
Another
You have entered this
'switch (userinput)' here 'switch' considering 'userinput' a string that should be integer,
You can fix it with this.
switch (eval(userinput))

Why is this switch statement not behaving as predicted?

I have the following switch block:
var str = 'matches[pw1]';
switch (str)
{
case (str.indexOf('matches') > -1) :
console.log('yes');
break;
default:
console.log(str.indexOf('matches') ) ;
console.log('no');
break;
}
What I want is, that if str contains the word 'matches', then it should run the first case block, otherwise the default block.
However when I run this, the output I get is '0', and then 'no', meaning the default block is running despite the conditions for the first case being met.
Any ideas what's wrong?
Your case is likely testing whether (str.indexOf('matches') > -1) == str.
EDIT:
It might be valuable to understand exactly what switch and case mean. One of Javascript's ancestors, C, commonly used switch to replace blocks of code where a primitive was being compared against a list of values (often from an enumeration, or a series of literals). So instead of:
if (type == ENABLE_FRAMISTAN)
{
enable_framistan();
}
else if (type == ENABLE_FROBSOSTICATOR)
{
enable_frobnosticator();
}
else if (type == DISABLE_BAZTICULATOR)
{
disable_bazticulator();
}
else
{
assert(false);
}
you could instead write:
switch (type)
{
case ENABLE_FRAMISTAN: enable_framistan(); break;
case ENABLE_FROBNOSTICATOR: enable_frobnosticator(); break;
case DISABLE_BAZTICULATOR: disable_bazticulator(); break;
default: assert(false); break;
}
...which might make it easier to digest (and or spot errors in) a large block of code which effectively mapped type values to functions being called (or some such). Your designated usage, checking to see whether a string matches any of a number of potential (exclusive with one another?) patterns, does not map as well to switch. If it were merely equality being tested, it would work well, but your condition is more sophisticated than switch was designed to express. Any way that you manage to preserve switch with your feature set will likely require less-than-obvious code.
Why not use an if statment? try something like this:
var str = 'matches[pw1]';
if(str.indexOf('matches') > -1) {
console.log('yes');
break;
}else{
console.log(str.indexOf('matches') ) ;
console.log('no');
break;
}
It should work since you don't have alot of cases anyways. I don't think you can do a comparing in cases.
What I want is, that if str contains the word 'matches', then it should run the first case block, otherwise the default block.
You cannot do that with a switch statement. A switch statement compares the result of evaluating the switch expression (in this case str) with the values of the case labels. The case labels can be expressions (as in your example), but if they are the expressions are evaluated and then compared against the value above using ===. (That's what the ECMAScript 5.1 spec says ...)
So what your code is actually doing for that case is (roughly speaking):
evaluate (str.indexOf('matches') > -1) which gives you true or false
compare true or false with the value of str ... which fails and the case body isn't executed.
Now I think you could make your approach work as follows:
case (str.indexOf('matches') > -1 ? str : '') :
console.log('yes');
break;
but that stinks from a code readability perspective (IMO).
You could do this:
console.log( str.indexOf( 'matches' ) > -1 ? 'yes' : 'no' );
You should know the basic usage of switch. I think you mistakenly use Switch. Try to use it as following:
var str = 'matches[pw1]';
str = str.indexOf('matches');
switch (str)
{
case -1 :
console.log('yes');
break;
default:
console.log(str.indexOf('matches') ) ;
console.log('no');
break;
}
Please look at the Following URL http://www.w3schools.com/js/js_switch.asp
If the above is not suitable for your logic, use if.. else if ...
http://www.w3schools.com/js/js_if_else.asp

jquery Using ranges in switch cases?

Switch cases are usually like
Monday:
Tuesday:
Wednesday:
etc.
I would like to use ranges.
from 1-12:
from 13-19:
from 20-21:
from 22-30:
Is it possible? I'm using javascript/jquery by the way.
you could try abusing the switch fall through behaviour
var x = 5;
switch (x) {
case 1: case 2: case 3: case 4: ...
break;
case 13: case 14: case 15: ...
break;
...
}
which is very verbose
or you could try this
function checkRange(x, n, m) {
if (x >= n && x <= m) { return x; }
else { return !x; }
}
var x = 5;
switch (x) {
case checkRange(x, 1, 12):
//do something
break;
case checkRange(x, 13, 19):
...
}
this gets you the behaviour you would like. The reason i return !x in the else of checkRange is to prevent the problem of when you pass undefined into the switch statement. if your function returns undefined (as jdk's example does) and you pass undefined into the switch, then the first case will be executed. !x is guaranteed to not equal x under any test of equality, which is how the switch statement chooses which case to execute.
Late to the party, but upon searching for an answer to the same question, I came across this thread. Currently I actually use a switch, but a different way. For example:
switch(true) {
case (x >= 1 && x <= 12):
//do some stuff
break;
case (x >= 13 && x <= 19):
//do some other stuff
break;
default:
//do default stuff
break;
}
I find this a lot easier to read than a bunch of IF statements.
You can make interesting kludges. For example, to test a number against a range using a JavaScript switch, a custom function can be written. Basically have the function test a give n value and return it if it's in range. Otherwise returned undefined or some other dummy value.
<script>
// Custom Checking Function..
function inRangeInclusive(start, end, value) {
if (value <= end && value >= start)
return value; // return given value
return undefined;
}
// CODE TO TEST FUNCTION
var num = 3;
switch(num) {
case undefined:
//do something with this 'special' value returned by the inRangeInclusive(..) fn
break;
case inRangeInclusive(1, 10, num):
alert('in range');
break;
default:
alert('not in range');
break;
}
</script>
This works in Google Chrome. I didn't test other browsers.
Nope, you need to use an if/else if series to do this. JavaScript isn't this fancy. (Not many languages are.)

Categories