在这种情况下,数组会比交换机更有效吗


Would an array be more effective than a switch case for this scenario?

我根据API的输入显示星级评定(注意:只显示,根本不接收评定)。下面的代码完全按照我的需要工作,但对于一些感觉可以被大规模简化的东西来说,这是一个非常大的逻辑块。

我在这里读到了其他一些观点,认为使用数组可能比切换情况更有效。但由于逻辑取决于一系列数字(如大于2.5但小于3)内true之间的每种情况,我不确定数组在这种情况下是否有效。

底线是:这个代码能以某种方式被大规模简化吗?

$stars = 3.5;
switch ($stars) {
  case ($stars > 1 && $stars <= 1.5):
    $star2 = 'dashicons-star-half';
    $star3 = 'dashicons-star-empty';
    $star4 = 'dashicons-star-empty';
    $star5 = 'dashicons-star-empty';
    break;
  case($stars > 1.5 && $stars <= 2):
    $star2 = 'dashicons-star-filled';
    $star3 = 'dashicons-star-empty';
    $star4 = 'dashicons-star-empty';
    $star5 = 'dashicons-star-empty';
    break;
  case($stars > 2 && $stars <= 2.5):
    $star2 = 'dashicons-star-filled';
    $star3 = 'dashicons-star-half';
    $star4 = 'dashicons-star-empty';
    $star5 = 'dashicons-star-empty';
    break;
  case($stars > 2.5 && $stars <= 3):
    $star2 = 'dashicons-star-filled';
    $star3 = 'dashicons-star-filled';
    $star4 = 'dashicons-star-empty';
    $star5 = 'dashicons-star-empty';
    break;
  case($stars > 3 && $stars <= 3.5):
    $star2 = 'dashicons-star-filled';
    $star3 = 'dashicons-star-filled';
    $star4 = 'dashicons-star-half';
    $star5 = 'dashicons-star-empty';
    break;
  case($stars > 3.5 && $stars <= 4):
    $star2 = 'dashicons-star-filled';
    $star3 = 'dashicons-star-filled';
    $star4 = 'dashicons-star-filled';
    $star5 = 'dashicons-star-empty';
    break;
  case($stars > 4 && $stars <= 4.5):
    $star2 = 'dashicons-star-filled';
    $star3 = 'dashicons-star-filled';
    $star4 = 'dashicons-star-filled';
    $star5 = 'dashicons-star-half';
    break;
  case($stars > 4.5):
    $star2 = 'dashicons-star-filled';
    $star3 = 'dashicons-star-filled';
    $star4 = 'dashicons-star-filled';
    $star5 = 'dashicons-star-filled';
    break;
  default:
  $star2 = 'dashicons-star-empty';
  $star3 = 'dashicons-star-empty';
  $star4 = 'dashicons-star-empty';
  $star5 = 'dashicons-star-empty';
}
?>
 <div class="wporg-ratings" title="<?php echo $stars; ?> out of 5 stars" style="color:#e6b800;">
   <span class="dashicons dashicons-star-filled"></span>
   <span class="dashicons <?php echo $star2; ?>"></span>
   <span class="dashicons <?php echo $star3; ?>"></span>
   <span class="dashicons <?php echo $star4; ?>"></span>
   <span class="dashicons <?php echo $star5; ?>"></span>
 </div>

我认为不需要数组或开关。您可以使用for循环,并根据循环变量检查$stars值,以查看应该使用哪个图标。

<div class="wporg-ratings" title="<?php echo $stars; ?> out of 5 stars" style="color:#e6b800;">
<?php
// for loop: one iteration for each of five possible stars
// (for loops are generally best for repeating code a specific number of times)
for ($i=0; $i < 5; $i++) {
    if ($stars <= $i ) {
        // empty stars are displayed when the iterator (i) is >= the star value
        echo  '<span class="dashicons dashicons-star-empty"></span>';
    } elseif ($stars <= $i + 0.5) {
        // half stars are displayed for star values between i and i+0.5 
        echo  '<span class="dashicons dashicons-star-half"></span>';
    } else {
        // whole stars are displayed when the star value is > i+0.5
        echo  '<span class="dashicons dashicons-star-filled"></span>';
    }
}
?>
</div>

为了帮助理解为什么这是有效的,通过循环获得一个理论值。我们可以使用您问题中的3.5

  • 第一次迭代:3.5>0,3.5>0.5,所以您得到else值(实心星形)
  • 第二次迭代:3.5>1,3.5>1.5,所以您得到else值(实心星)
  • 第三次迭代:3.5>2,3.5>2.5,所以您得到else值(实心星)
  • 第四次迭代:3.5>3,3.5=3.5,所以得到elseif值(半星)
  • 第五次迭代:3.5<4,所以你得到if值(空星)

这里是快速版本:

$stars = 3.5;
$d = array(
    ($stars >= 1.0) ? 'dashicons-star-filled' : (($stars >= 0.5) ? 'dashicons-star-half' : 'dashicons-star-empty'),
    ($stars >= 2.0) ? 'dashicons-star-filled' : (($stars >= 1.5) ? 'dashicons-star-half' : 'dashicons-star-empty'),
    ($stars >= 3.0) ? 'dashicons-star-filled' : (($stars >= 2.5) ? 'dashicons-star-half' : 'dashicons-star-empty'),
    ($stars >= 4.0) ? 'dashicons-star-filled' : (($stars >= 3.5) ? 'dashicons-star-half' : 'dashicons-star-empty'),
    ($stars >= 5.0) ? 'dashicons-star-filled' : (($stars >= 4.5) ? 'dashicons-star-half' : 'dashicons-star-empty')
);
echo '<div class="wporg-ratings" title="' . $stars . ' out of 5 stars" style="color:#e6b800;">';
foreach ($d as $value) echo '<span class="dashicons ' . $value . '"></span>';
echo '</div>';

它和你最初的逻辑不一样(当第一颗星总是被填满时),但你可以把它用作方向

下一步可能是将重复的代码移动到函数

另一种可能性是定义一个散列数组。假设数组中的每个元素都包含"最小值和三个字符串",并且数组按升序排序。if/then逻辑可以被通过该数组的循环所取代,并在可能的情况下尽快爆发。

但是: "清晰性胜过所有其他问题。"如果代码有效且可合理维护,谁在乎它是否有臭味?

通过注意if条件的前半部分可以省略,可以简化现有代码,以消除任何值"从裂缝中掉下来"的可能性:如果达到第二种情况,则该值必须大于1.5,依此类推。