这个if语句怎么了?轨道

时间:2016-01-15 22:23:01

标签: ruby-on-rails ruby ruby-on-rails-4

我正在建立一个声誉系统,如果达到里程碑(10,100,1000,...),用户将获得积分。我有这个if语句行:

if (before_points < ((10 || 100 || 1000 || 10000 || 100000 || 1000000))) && (after_points >= ((10 || 100 || 1000 || 10000 || 100000 || 1000000)))

如果小于10或100或1000之前的点,并且如果这些点大于或等于10或100或1000 ......之后,它应该返回true。

如果它之前低于10,之后超过10,它可以工作,我不太确定它是否适用于100,但如果之前的点数低于1000且之后超过1000,则无效。

这是正确的方法吗?用开关/盒子做这件事会更好吗?

3 个答案:

答案 0 :(得分:2)

这不是逻辑运算的真正运作方式。声明:

(10 || 100 || 1000 || 10000 || 100000 || 1000000)

将评估为10。 2个或更多数字之间的||运算符将返回第一个非nil值,在这种情况下为10,即第一个值。 Related question

即使不是这种情况,如果before_points < 10为真,before_points < 1000000也为真,如果只有before_points < 1000000为真,则if语句仍会执行与before_points < 10一样,所以逻辑错误。

根据您要解决的问题,您可以使用case或在数组中定义里程碑并迭代值10,100,...,1000000,每次条件仍为真时设置新里程碑。

答案 1 :(得分:2)

你可以采用更紧凑的方式......

 <?php
 $sth = $dbh->prepare("CALL test1()");
 $sth->execute();

 $results = array();
 do {
    $rowset = $sth->fetchAll();
    if($rowset) {
       $results [] = $rowset;
    }
 } while ($sth->nextRowset());

 ?>

如果跨越边界,该表达式将返回[10, 100, 1000, 10000, 100000, 1000000].any?{|n| before_points < n && after_points >= n} ,否则将返回true

答案 2 :(得分:1)

你的假设是错误的。

if (before_points < ((10 || 100 || ...

将首先评估该部分

10 || 100

总是返回10,因为10评估为真,因此这行

if (before_points < ((10 || 100 || 1000 || 10000 || 100000 || 1000000))) && (after_points >= ((10 || 100 || 1000 || 10000 || 100000 || 1000000)))

实际上与

相同
if (before_points < 10) && (after_points >= 10)

我不确定你想要达到什么目标,但使用案例可能更好(这只是一个例子)

case
  when before_points < 10 && after_points >= 10
  # ...
  when before_points < 100 && after_points >= 100
  # ...
  else
  # ...
end