So while playing around with some js code, I came across something interesting. The problem statement goes like-
Given a string, use switch case to evaluate the following conditions:-
If the first character in string is in the set {a, e, i, o, u}, then return A.
If the first character in string is in the set {b, c, d, f, g}, then return B.
If the first character in string is in the set {h, j, k, l, m}, then return C.
If the first character in string is in the set {n, p, q, r, s, t, v, w, x, y, z}, then return D.
And I KNOW that this is not the best implementation, so don't @ me.
function getLetter(s) {
let letter;
switch(s[0]){
case 'a'||'e'||'i'||'o'||'u':
letter='A'
break
case 'b'||'c'||'d'||'f'||'g':
letter='B'
break
case 'h'||'j'||'k'||'l'||'m':
letter='C'
break
case 'n'||'p'||'q'||'r'||'s'||'t'||'v'||'w'||'x'||'y'||'z':
letter='D'
break
}
return letter;
All cases except the last one work fine. In the last case, the value of 'letter' is set to 'D' only if the string begins with 'n' & not for any other characters in the case label. Why is this happening? Genuinely Curious.
3 Answers 3
Actually, getLetter('e') also returns undefined.
switch(s[0]){
case 'a': case 'e': case 'i':: case 'o': case 'u':
letter='A'
break
case 'b': case 'c': case 'd': case 'f': case 'g':
letter='B'
break
case 'h': case 'j': case 'k': case 'l': case 'm':
letter='C'
break
case 'n': case 'p': case 'q': case 'r': case 's': case 't': case 'v': case 'w': case 'x': case 'y': case 'z':
letter='D'
break
}
will work as you wanted.
Also, if there is a guarantee that s[0] is alphabet, you can rewrite:
default:
letter='D'
break
Comments
This is not working for any of the other cases as well. it's only evaluating the first case.
If you want to use multiple cases you should do it in this format:
switch(s[0]){
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
letter = 'A'
break;
case 'b':
case 'c':
...
...
letter = 'B'
break;
...
}
Comments
In JavaScript, a || b returns the value of a if it is truthy (this is commonly answered elsewhere on Stack Overflow). Since non-empty strings are truthy, this is what your switch statement effectively looks like:
switch(s[0]){
case 'a':
letter='A'
break
case 'b':
letter='B'
break
case 'h':
letter='C'
break
case 'n':
letter='D'
break
}
In other words, all the || bits are effectively made irrelevant, and your switch statement is really only accounting for four letters.
switchwould resolve this problem.x || yis an expression, it is evaluated the same way in any context, including when you use it as acaselabel in a switch. Its value is the value ofxif the value ofxis true when it is evaluated as boolean or the value ofyotherwise (no matter the value ofy). This means the value of'a'||...is always'a', no matter what other values you put after the logical OR operator.