我有以下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
答案 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。