Suppose I have a variable integer and wish to do different things if the value is greater then one value and less then another value. My objective for this switch, is basically to send different results based on the value of $chance, which I will have many cases in the end as this is for a game.
switch ($chance)
{
case ($chance < 15):
echo"strike<br>";
case ($chance < 15 && $chance > 50):
echo"Ball<br>";
break;
case ($chance < 50 && $chance > 100):
echo"Single<br>";
break;
case ($chance <= 150 && $chance >= 100):
echo"double<br>";
break;
case ($chance <= 175 && $chance >= 151):
echo"triple<br>";
break;
case ($chance > 200 && $chance > 175):
echo"Ground Rule Double<br>";
break;
case ($chance < 200):
echo"Home Run<br>";
break;
}
Now, I've been told that I can use conditionals in switch statements, and I've also been told that I should not use them. I really don't know who to believe.
What I do know, is that currently, this switch statement does not work as intended. It doesn't generate syntax errors, but I will get random echos back. This happens when sometimes the chance may be 100 and I will get a home run echo. I'm not sure.
I know I could do the same with a series of if but it would amount to a huge difference in length of code if I can achieve the same results.
I imagine I can do something like
case 1:
echo this
case 2:
echo that
etc etc
Until I hit 2 or 300 but I would like to avoid that if possible.
This is not how you use the switch statement. This is an example of a correct way:
switch ($a) {
case 1:
echo 1;
break;
case 2:
echo 2;
break;
default:
echo 0;
}
For what you want to accomplish you need to use the old if-else statements.
if ($chance < 15)
echo"strike<br>";
else if ($chance >= 15 && $chance < 50)
echo"Ball<br>";
else if ($chance >= 50 && $chance < 100)
echo"Single<br>";
else if ($chance <= 150 && $chance >= 100)
echo"double<br>";
else if ($chance <= 175 && $chance >= 151)
echo"triple<br>";
else if ($chance < 200 && $chance > 175)
echo"Ground Rule Double<br>";
else if ($chance <= 200)
echo"Home Run<br>";
Switch statement syntax:
http://php.net/manual/en/control-structures.switch.php
<?php
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
default:
echo "i is not equal to 0, 1 or 2";
}
?>
To do what you are wanting to do, you should use an if-else. The value used for the case expression must be an integer, floating-point decimal, or string.
You need just set true in you switch. Use switch (true) instead of switch ($chance).
now your code will be:
switch (true)
{
case ($chance < 15):
echo"strike<br>";
case ($chance < 15 && $chance > 50):
echo"Ball<br>";
break;
case ($chance < 50 && $chance > 100):
echo"Single<br>";
break;
case ($chance <= 150 && $chance >= 100):
echo"double<br>";
break;
case ($chance <= 175 && $chance >= 151):
echo"triple<br>";
break;
case ($chance > 200 && $chance > 175):
echo"Ground Rule Double<br>";
break;
case ($chance < 200):
echo"Home Run<br>";
break;
}
Despite some mathematical/comparison issues in your code, it seems that you intend to set numeric ranges that correspond to specific outcomes. It also seems inappropriate to reach multiple outcomes in a single script execution.
Given these truths, you should use an if-elseif-else block. It will be more appropriate and less verbose than a switch block.
The ONLY advantage to using a switch block is when you need to make 1 evaluation and take different actions based on that evaluation. Because you are making multiple evaluations, there is no advantage in using a switch -- in fact, the computational complexity will be the same and the syntax will either be of equal or greater length versus an if block. I personally have such a distaste for switch blocks that I endeavor to use any other viable technique instead. Switch blocks only make very rare appearances in my professional projects.
By progressing in an ASC or DESC fashion, you will only need one expression in each condition. Using consistent operators in each condition will make your script easier to maintain/extend.
Finally, in PHP, elseif is one word not two.
Code:
if ($chance < 0) {
$result = 'Balk'; // ;)
} elseif ($chance < 15) {
$result = 'Strike';
} elseif ($chance < 50) {
$result = 'Ball';
} elseif ($chance < 100) {
$result = 'Single';
} elseif ($chance < 150) {
$result = 'Double';
} elseif ($chance < 175) {
$result = 'Triple';
} elseif ($chance < 200) {
$result = 'Ground Rule Double';
} else {
$result = 'Home Run';
}
echo "$result<br>";
Related
I wrote the following piece of code to perform a custom rating of some movies in accordance to their IMDb rating (I'm scraping the rating field off of IMDb using a class I found on github).
Anyway, this worked fine for 643 movies in my DB, but for 12 specific movies it fails to recognize the correct range the IMDb rating corresponds to... It's not that those 12 have any special number instead of a rating... I wrote down the values of those 12 movies, and they are normal floats (OK, except for one that is a very old, foreign movie and it returns n/A - but even that when floatval()'ed turns to 0)... For statistical reasons, the values that can't be recognized along with the times they appear are these:
1x time 0 [it's the unrated one]
2x times a rating of 3.4
2x times a rating of 3.8
4x times a rating of 3.9
1x time a rating of 4.1
2x times a rating of 4.6
The code that performs this custom rating is this (very simple and straight-forward):
$rating = floatval($imdb->getRating());
switch (true) {
case in_array($rating, range(1, 4.9, 0.1)):
$return['movie_rating'] = 1;
break;
case in_array($rating, range(5, 5.9, 0.1)):
$return['movie_rating'] = 2;
break;
case in_array($rating, range(6, 6.9, 0.1)):
$return['movie_rating'] = 3;
break;
case in_array($rating, range(7, 7.9, 0.1)):
$return['movie_rating'] = 4;
break;
case in_array($rating, range(8, 10, 0.1)):
$return['movie_rating'] = 5;
break;
default:
$return['movie_rating'] = 'n/A';
}
Guys, honestly, this is driving me crazy. Any suggestion will be very much appreciated! TIA.
problem happens because of floating point math is not precise
to avoid it I suggest to rewrite this code this way:
if ($rating >= 8) $return['movie_rating'] = 5;
elseif ($rating >= 7) $return['movie_rating'] = 4;
elseif ($rating >= 6) $return['movie_rating'] = 3;
elseif ($rating >= 5) $return['movie_rating'] = 2;
elseif ($rating >= 1) $return['movie_rating'] = 1;
else $return['movie_rating'] = 'n/A';
When I use 0 for input, it outputs me this Between 100 and 200. With other values it works fine. Can someone explain me why this is happening?
http://prntscr.com/n7fzcy
<?php
$num = intval(readline());
switch ($num) {
case $num < 100:
echo "Less than 100";
break;
case $num >= 100 && $num <= 200:
echo "Between 100 and 200";
break;
default:
echo "Greater than 200";
}
You can't use any logical operators <,>,!=,=,== .... in switch case statements.
Use a simple if else condition:
$num = intval(readline());
if($num < 100){
echo "Less than 100";
}else if($num >= 100 && $num <= 200){
echo "Between 100 and 200";
}else{
echo "Greater than 200";
}
I'm currently working on a foreach loop with nested if statements but I'm pretty sure there's a better way of writing these chunks of if statements.
I found this post: PHP if shorthand and echo in one line - possible?
Though this post is for single conditions, I would like to write mine in the same way(single lined).
I'm not that experienced in PHP myself so I'm sort of stuck on doing it the old fashioned way:
if(($colorLevel['name'] === 'ATTR_VPMCV13') && ($colorLevel['level'] >= 80))
{
$prominentSideNumberArray[] = 10;
}
elseif(($colorLevel['name'] == 'ATTR_VPMCV13') && ($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)){
$prominentSideNumberArray[] = 8;
}
If someone could properly explain what code to use where and why, that could really help me, and/or others, out. I've looked at the manual but I just can't figure out what to use where.
There is no such thing like an "if shorthand".
?: is an operator, if is a control structure. They are different language concepts that have different purposes and do different things. An expression that contains the ternary conditional operator (?:) can always be rewritten as two expressions and an if/else statement. The vice-versa is usually not possible.
The code you posted can be written to be much easier to read if you extract the common checking of $colorLevel['name'] into a separate if that includes the rest of the tests, extract $colorLevel['level'] into a new variable with shorter name and make the conditions that use $colorLevel['level'] use the same rule:
$level = $colorLevel['level'];
if ($colorLevel['name'] == 'ATTR_VPMCV13') {
// Don't mix '<=' with '>=', always use '<='...
if (60 <= $level && $level <= 70) {
$prominentSideNumberArray[] = 8;
// ... and put the intervals in ascending order
} elseif (80 <= $level) {
$prominentSideNumberArray[] = 10;
}
}
If there are multiple if statements that verify different values of $colorLevel['name'] then the intention is more clear if you use a switch statement:
$level = $colorLevel['level'];
switch ($colorLevel['name'])
{
case 'ATTR_VPMCV13':
if (60 <= $level && $level <= 70) {
$prominentSideNumberArray[] = 8;
} elseif (80 <= $level) {
$prominentSideNumberArray[] = 10;
}
break;
case '...':
// ...
break;
default:
// ...
break;
}
You can achieve this by using a ternary operator. Look at the following code:
$prominentSideNumberArray[] = ((($colorLevel['name'] === 'ATTR_VPMCV13') &&
($colorLevel['level'] >= 80) )? 10 : (($colorLevel['name'] == 'ATTR_VPMCV13') &&
($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)?8:"")) ;
EDIT As per comments and you have to compare same value its better to define name
$color_name = "ATTR_VPMCV13";
if($colorLevel['name'] == $color_name )
$prominentSideNumberArray[] = (($colorLevel['level'] >= 80)? 10 : (
($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)?8:"")) ;
DEMO with different approach
EDIT
Keep in mind that this solution is less readable than if-else statement.
This question already has answers here:
The 3 different equals
(5 answers)
Closed 7 years ago.
I have a strange case issue, in my php code;
$sm_hours = (int)$sm_hours; // Make it an integer
echo $sm_hours; // is 206
switch ($sm_hours) {
case ($sm_hours = 0 && $sm_hours <= 120):
echo "One";
break;
case ($sm_hours >= 121 && $sm_hours <= 240):
echo "Two";
break;
case ($sm_hours >= 241):
echo "Three";
break;
}
$sm_hours is 206 but the echo I get is One not Two. What have I missed?
Thanks
You will always jump into the first switch case because you are setting $sm_hours to 0. A single = is used to set the variable.
To test its value use == which will perform type juggling, or use === to test the type also.
case ($sm_hours == 0 && $sm_hours <= 120):
you are using equality operator
In case one, try this:
case ($sm_hours == 0 && $sm_hours <= 120):
echo "One";
break;
Better use if and elseif statements in your case:
$sm_hours = (int)$sm_hours; // Make it an integer
echo $sm_hours; // is 206
if ($sm_hours >= 0 && $sm_hours <= 120)
echo "One";
elseif ($sm_hours >= 121 && $sm_hours <= 240)
echo "Two";
else
echo "Three";
switch just tries to match exact values.
try
$sm_hours >= 0 && $sm_hours <=120
Ok, so this works taking into account where $sm_hours is < 120 as pointed out by Anand. This code works for all options that I need.
switch ($sm_hours) {
case ($sm_hours >= 121 && $sm_hours <= 240):
echo "Two";
break;
case ($sm_hours >= 241):
echo "Three";
break;
default:
echo "One";
break;
}
I am trying to say $level > -100 && $level < 100
$level = 0;
switch($level){
case $level > -100:
break;
case $level < 100:
break;
default:
echo '5';
return null;
}
can you use a switch statement like this.
None of the answers presented so far have explicitly connected the spirit of the original question with a proper switch construction. So, for the record:
switch (true) {
case (($level>-100) && ($level<100)):
echo 'in range one';
break;
case (($level>200) && ($level<300)):
echo 'in range two';
break;
default:
echo 'out of range';
}
There's absolutely nothing wrong with this usage of switch.
When you say switch ($level) you're already comparing the value of $level. Each case can then only check for equality, you can't do comparisons like in your example. You'll have to use an if statement instead:
if ($level > -100 && $level < 100)
; // do nothing; equivalent of break in this case
else
echo '5';
Even simpler, just negate the conditions:
if ($level <= -100 || $level >= 100)
echo '5';
Apart of if/else, another way to do it:
switch (true)
case $level > -100:
break;
case $level < 100:
break;
default:
echo '5';
return null;
}
The other answers are both correct and incorrect at the same time. Incorrect, in that it is possible to do what you want in PHP... change switch($level) to switch(true) and your example will work. Correct, in that it's bad form and if any other programmers see that in your code they'll probably come after you with pitchforks. Its not how the switch statement is intended to be used, and wouldn't work like that in most other languages.
No you can't. Switch does only 'equals' type comparison.
No, you can't. The switch statement needs literals in the case blocks. Use an if statements instead:
if(!($level > -100 && $level < 100))
{
echo '5';
return null;
}
This is one of the reasons people advocating case as a superior solution to if-else are off base. I don't like the syntax or the limitations - if-ifelse-else is much more useful.