这个Ruby CASE语句有什么问题?

时间:2011-05-27 16:32:26

标签: ruby

我有以下ruby函数,当我把它称为'deg_to_dir 270'时,case语句永远不会匹配,当它应该返回W.我一直在拉我的头发而没有把整个东西转换为IF语句我不喜欢没有下一步。

def deg_to_dir deg
  # used logic from http://www.csgnetwork.com/degrees2direct.html
  d = deg.to_f
  dir = "#{d}°"
  case d
    when d >=  0    && d <=  11.25,
         d > 348.75 && d <= 360
      dir = "N"
    when d >  11.25 && d <=  33.75
      dir = "NNE"
    when d >  33.75 && d <=  56.25
      dir = "NE"

    when d >  56.25 && d <=  78.75
      dir = "ENE"
    when d >  78.75 && d <= 101.25
      dir = "E"
    when d > 101.25 && d <= 123.75
      dir = "ESE"

    when d > 123.75 && d <= 146.25
      dir = "SE"
    when d > 146.25 && d <= 168.75
      dir = "SSE"
    when d > 168.75 && d <= 191.25
      dir = "S"
    when d > 191.25 && d <= 213.75
      dir = "SSW"
    when d > 213.75 && d <= 236.25
      dir = "SW"

    when d > 236.25 && d <= 258.75
      dir = "WSW"
    when d > 258.75 && d <= 281.25
      dir = "W"
    when d > 281.25 && d <= 303.75
      dir = "WNW"
    when d > 303.75 && d <= 326.25
      dir = "NW"
    when d > 326.25 && d <= 348.75
      dir = "NNW"
  end
  dir
end

6 个答案:

答案 0 :(得分:7)

您要做的是if elsif模式。如果您尝试使用case when模式,则应使用范围:

case d
when (0..11.25)
  dir = "N"
when (11.25..33.75)
  dir = "NE"
  # etc...
end

每次解析器执行时,它都会执行case_statement === when_statement。所有when语句都计算为布尔值,它永远不会等于度。

答案 1 :(得分:4)

我会说case声明中最糟糕的部分是它根本不应该是case声明。

DIRS = %w[N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW]

def deg_to_dir deg
  deg = deg.to_f
  dir = DIRS[(deg + 11.25).div(22.5)]
  "#{deg}° #{dir}"
end

答案 2 :(得分:3)

如果您不想比较某个值,而是“模拟”if-else with case(如您的情况),您只需编写

case

而不是

case d

答案 3 :(得分:2)

问题在于你在case d中写了when和一个布尔条件(所以它执行true|false === d,它永远不会成功)。它应该看起来像这样(注意如何利用case作为Ruby中的表达式):

dir = case 
  when d >=  0    && d <=  11.25,
       d > 348.75 && d <= 360
  "N"
  ...
end

无论如何,为什么不在没有条件的情况下重构这种方法呢? IMO这是一个非常差的实现;你应该需要一个带有缩写名称的数组(以及明智地使用它的代码)。可能是一个/两个班轮。

答案 4 :(得分:1)

将Kyle和tokland的答案结合起来,你最终将会关注:

def deg_to_dir deg
  case deg.to_f
  when (0..11.25)
    "N"
  when (11.25..33.75)
    "NE"
  # ... your rest ...
  end
end

没有辅助变量!

答案 5 :(得分:0)

凯尔对范围的回答是正确的。原因是case语句使用===。

将d与when语句进行比较

在这种情况下,您正在进行

的比较
270 === true

不是。对于float和bool的任何值,float都不会等于boolen。