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
Related
//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');
}
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");
}
switch (req.path)
{
case "/api/posts":
console.log("posts");
break;
case "/api/posts/tags/*": // the part * is always changing depending on user input
console.log("tags");
break;
case "/api/best":
console.log("best");
break;
default:
console.log("default");
}
the req.path gives my path
for example
/api/post/tags/asd,dsfd
/api/post/tags/1
/api/post/tags/12,123
how do you manage with this as efficiently as possible?
some frameworks provide path parsers that looks like
/*
this and any input after * is ignored and treated as the same. I am curious of its inner mechanism.
What about something like this (see the jsfiddle):
function route(req) {
if(req.path === '/api/posts') {
console.log('posts');
}
if(req.path.indexOf('/api/posts/tags') > -1) {
console.log('tags');
}
// etc.
}
route({path: '/api/posts'}); // => posts
route({path: '/api/posts/tags/hi'}); // => tags
route({path: '/api/posts/tags/cool'}); // => tags
You could also use a regular expression. Keep in mind that if some input conditions might match each other, you'll want to return at the end of each if statement, or simply use else if. Totally depends on the routes your looking for.
For the default case, you can string together everything with if... else if, and in the final else put console.log('default'). I've left my above solution very minimal so you can extend it as you see fit.
Output
You can just toss a regex into your switch statement which will handle all cases branching off of that route.
switch (req.path)
{
case "/api/posts":
console.log("posts");
break;
case req.path.match(/(\/api\/posts\/tags\/)/)[1]:
console.log("tags");
break;
case "/api/best":
console.log("best");
break;
default:
console.log("default");
}
So lets say I had this switch:
switch(str){
case "something": //a defined value
// ...
break;
case /#[a-zA-Z]{1,}/ //Matches "#" followed by a letter
}
I'm almost sure that the above is almost impossible...but what would be the best way to achieve something similar? Maybe just plain if..else..ifs? That'd be boring...
So how would you achieve this?
You can get the matches for various patterns before you begin the switch,
and set the cases to the index of the match.
(Other conditionals would be easier to read, if not more efficient.)
//var str= 'something';
var str='#somethingelse';
var M= /^(something)|(#[a-zA-Z]+)$/.exec(str);
if(M){
switch(M[0]){
case M[1]:
// ...
alert(M[1]);
break;
case M[2]:
//...
alert(M[2])
break;
}
}
You can use a single regexp. It is not necessarily less boring but it gets the job done.
var result = /(something)|(#[a-zA-Z]{1,})/.exec(str);
if (!result) {
// Handle error?
} else if (result[1]) {
// something
} else if (result[2]) {
// #[a-zA-Z]{1,}
}
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 ===.