Switch 不适用于数字比较案例

Posted

技术标签:

【中文标题】Switch 不适用于数字比较案例【英文标题】:Switch doesn't work with numeric comparison cases 【发布时间】:2014-03-06 03:52:49 【问题描述】:

这是我的代码。

$value = 0;
switch($value) 
      case ( $value <= 25 ):
            $CompScore = 'low';
            break;
      case ($value > 25 && $value <= 50 ):
            $CompScore = 'fair';
            break;
      case ($value > 50 && $value <= 75 ):
            $CompScore = 'good';
            break;
      case ($value >75 ):
            $CompScore = 'excellent';
            break;
      default:
            $CompScore = 'low';
            break;


echo $CompScore;

当值为0时,$compScorefair。为什么它没有显示low?我不明白为什么。

【问题讨论】:

这不是开关块的使用方式。使用开关的原因是评估 $value ONCE 然后检查合格的案例值。因为您正在对$value 执行单独的评估,所以您可以使用if-elseif-else 块更简洁地编写同样高效的代码。最好的方法是将isset() 与查找数组一起使用,并在输入不属于预期组之一时分配默认值。 (正如我的回答所证明的) 【参考方案1】:

switch 不是那样工作的。

因为 $value0 这是假值。

$value &lt;= 25true$value &gt; 25 &amp;&amp; $value &lt;= 50false,所以 $CompScore 将是 'fair'

对于您的代码,使用if elseif else 流将更具可读性。

你可以像下面这样重写你的代码:

// from excellent to low
if ($value > 75) 
  $CompScore = 'excellent';
 else if ($value > 50) 
  $CompScore = 'good';
 else if ($value > 25) 
  $CompScore = 'fair';
 else 
  $CompScore = 'low';

【讨论】:

【参考方案2】:

问题是,你以一种特殊的方式使用你的开关。

你是说:

$value = 0;
Switch ($value)
    case ($value < 25):
        ....


这最终比较了 $value

($value<25) == $value.
=> true == 0

这是错的,因为true != 0

以这种方式做你想做的事情的一种方法是将switch($value)替换为switch(true),这样解释器将实际比较检查你的case语句是否正确。

【讨论】:

【参考方案3】:

您传递给 switch 语句的值基本上是 switch 语句寻找评估匹配的值,从上到下向下查找案例列表,直到找到一个 等于 到 (松散的比较),例如true == true

在您的示例中,您的 comparisons 被评估为布尔值(真或假) - 您的变量 $value 设置为零,这 等于false,但不是 相同(严格比较)与false。例如:

(0 == false)    // true
(0 === false)   // false
(1 == false)    // false
(1 === false)   // false
(1 == true)     // true
(1 === true)    // false
(true === true) // true

因此,通过使用布尔值 true 作为您的开关值,您可以在语句中使用 数字比较,其中每个比较将评估为 truefalse匹配/不匹配原始 true 值(布尔 - 布尔比较)。

switch(true) 
       case ($value <= 25):                 // true
             $CompScore = 'low';
             break;
       case ($value > 25 && $value <= 50 ): // false
             $CompScore = 'fair';
             break;
       case ($value > 50 && $value <= 75 ): // false
             $CompScore = 'good';
             break;
       case ($value >75 ):                  // false
             $CompScore = 'excellent';
             break;
       default:                             // if you removed the first case
             $CompScore = 'low';            // this default case would be used
             break;                         
 

【讨论】:

以为问题是“为什么它没有显示低?” 示例确实显示低。为什么这被否决了?合理的话会删掉。 你没有解释为什么它不能使用原始代码。【参考方案4】:

您可以使用查找数组和一些简单的数学运算来“智能”您的代码。

代码:(Demo)

$lookup = [
    1 => 'low',
    2 => 'fair',
    3 => 'good',
    4 => 'excellent'
];

for ($i = -1; $i <= 101; ++$i) 
    echo "\n$i : " , $lookup[ceil($i / 25)] ?? $lookup[1];

通过将该值除以 25,然后四舍五入到下一个整数(使用ceil()),您可以在没有一系列条件语句的情况下获得相同的结果。使用查找功能不仅可以保持代码紧凑,还可以确保您不会对相同的值执行 n 检查,并且可以在进程和值之间提供清晰的分离。

如果您决定将组拆分为 20,而不是 25,您只需将 25 更改为 20,然后在所需位置添加第五个查找值(使用适当的键)。

【讨论】:

以上是关于Switch 不适用于数字比较案例的主要内容,如果未能解决你的问题,请参考以下文章

与 XSLT 进行区域感知数字比较

比较并交换不适用于许多核心

字符串比较似乎不适用于从文件中读取的行

v-bind:style 指令不适用于条件比较

SQL - 左连接不适用于 switch 语句

React Router v4 - 重定向不适用于 Switch