php switch case 语句来处理范围
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8876620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
php switch case statement to handle ranges
提问by nikhil
I'm parsing some text and calculating the weight based on some rules. All the characters have the same weight. This would make the switch statement really long can I use ranges in the case statement.
我正在解析一些文本并根据一些规则计算权重。所有字符的权重相同。这将使 switch 语句变得很长,我可以在 case 语句中使用范围。
I saw one of the answers advocating associative arrays.
我看到了提倡关联数组的答案之一。
$weights = array(
[a-z][A-Z] => 10,
[0-9] => 100,
['+','-','/','*'] => 250
);
//there are more rules which have been left out for the sake of clarity and brevity
$total_weight = 0;
foreach ($text as $character)
{
$total_weight += $weight[$character];
}
echo $weight;
What is the best way to achieve something like this? Is there something similar to the bash case statement in php? Surely writing down each individual character in either the associative array or the switch statement can't be the most elegant solution or is it the only alternative?
实现这样的目标的最佳方法是什么?有没有类似于php中的bash case语句的东西?当然,写下关联数组或 switch 语句中的每个字符都不是最优雅的解决方案,还是唯一的选择?
采纳答案by akond
$str = 'This is a test 123 + 3';
$patterns = array (
'/[a-zA-Z]/' => 10,
'/[0-9]/' => 100,
'/[\+\-\/\*]/' => 250
);
$weight_total = 0;
foreach ($patterns as $pattern => $weight)
{
$weight_total += $weight * preg_match_all ($pattern, $str, $match);;
}
echo $weight_total;
*UPDATE: with default value *
*更新:使用默认值 *
foreach ($patterns as $pattern => $weight)
{
$match_found = preg_match_all ($pattern, $str, $match);
if ($match_found)
{
$weight_total += $weight * $match_found;
}
else
{
$weight_total += 5; // weight by default
}
}
回答by Sudhir Bastakoti
Well, you can have ranges in switch statement like:
好吧,您可以在 switch 语句中设置范围,例如:
//just an example, though
$t = "2000";
switch (true) {
case ($t < "1000"):
alert("t is less than 1000");
break
case ($t < "1801"):
alert("t is less than 1801");
break
default:
alert("t is greater than 1800")
}
//OR
switch(true) {
case in_array($t, range(0,20)): //the range from range of 0-20
echo "1";
break;
case in_array($t, range(21,40)): //range of 21-40
echo "2";
break;
}
回答by Arrix
You can specify the character range using regular expression. This saves from writing a really long switch case list. For example,
您可以使用正则表达式指定字符范围。这样可以避免编写非常长的开关案例列表。例如,
function find_weight($ch, $arr) {
foreach ($arr as $pat => $weight) {
if (preg_match($pat, $ch)) {
return $weight;
}
}
return 0;
}
$weights = array(
'/[a-zA-Z]/' => 10,
'/[0-9]/' => 100,
'/[+\-\/*]/' => 250
);
//there are more rules which have been left out for the sake of clarity and brevity
$total_weight = 0;
$text = 'a1-';
foreach (str_split($text) as $character)
{
$total_weight += find_weight($character, $weights);
}
echo $total_weight; //360
回答by Eugene X
Much different ways to do this.
很多不同的方法来做到这一点。
$var = 0;
$range_const = range(10,20);
switch ($var) {
case 1: $do = 5; break; # 1
case 2: $do = 10; break; # 2
case 3:
case 4:
case 5: $do = 15; break; # 3, 4, 5
default:
if ($var > 5 && $var < 10) { # High performance (6..9)
$do = 20;
} else if (in_array($var, $range_const, true)) { # Looks clear (10..20)
$do = 25;
} else { # NOT in range 1..20
$do = -1;
}
}
print($do);
There no direct range X..Y compares because $var checks to true in each step, but this allows do some nice cheating like this...
没有直接的范围 X..Y 比较,因为 $var 在每一步都检查为真,但这允许做一些像这样很好的作弊......
$in = create_function('$a,$l,$h', 'return $a>=$l && $a<=$h;');
$var = 4;
switch (true) {
case ($var === 1): echo 1; break;
case ($var === 2): echo 2; break;
case $in($var, 3, 5): echo "3..5"; break;
case $in($var, 6, 10): echo "6..10"; break;
default: echo "else";
}
回答by phoenix
If you have a more complex conditions, you can wrap them inside a function. Here's an oversimplified example:
如果您有更复杂的条件,您可以将它们包装在一个函数中。这是一个过于简化的例子:
$chartID = 20;
$somethingElse = true;
switch (switchRanges($chartID, $somethingElse)) {
case "do this":
echo "This is done";
break;
case "do that":
echo "that is done";
break;
default:
echo "do something different";
}
function switchRanges($chartID, $somethingElse = false)
{
if (in_array($chartID, [20, 30]) && $somethingElse === true) {
return "do this";
}
if (in_array($chartID, [20, 50]) && $somethingElse === false) {
return "do that";
}
}
回答by Pedro Mora
I think I would do it in a simple way.
我想我会以一种简单的方式做到这一点。
switch($t = 100){
case ($t > 99 && $t < 101):
doSomething();
break;
}