Php switch case statement для обработки диапазонов
Я разбираю текст и вычисляю вес, основанный на некоторых правилах. Все персонажи имеют одинаковый вес. Это сделало бы оператор switch действительно длинным, я могу использовать диапазоны в выражении case.
Я увидел один из ответов, защищающий ассоциативные массивы.
$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;
Каков наилучший способ добиться чего-то подобного?
Есть ли что-то похожее на оператор case bash в php?
Несомненно, запись каждого отдельного символа в ассоциативном массиве или оператор switch не может быть самым изящным решением или это единственная альтернатива?
Ответы
Ответ 1
$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: со значением по умолчанию *
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
}
}
Ответ 2
Ну, вы можете иметь диапазоны в инструкции 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;
}
Ответ 3
Вы можете указать диапазон символов, используя регулярное выражение. Это избавляет от написания очень длинного списка событий коммутатора. Например,
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
Ответ 4
Думаю, я сделал бы это простым способом.
switch($t = 100){
case ($t > 99 && $t < 101):
doSomething();
break;
}