mar*_*ion 3 ruby ruby-on-rails-5
我有这样的声明:
> zv.sum(:volume).to_f || 1.0
(0.5ms) SELECT SUM("positions"."volume") FROM "positions" WHERE "positions"."volume" = $1 [["volume", 0]]
=> 0.0
Run Code Online (Sandbox Code Playgroud)
我想要发生的是 ifzv.sum(:volume)返回0.0,我希望它返回1.0。
我知道我可以做一个冗长的if/unless语句,但我想在上面的 1 行中优雅地做它。
我怎么做?
您的标题和问题中确实有解决方案(我的粗体强调):
如果在 1 行中返回的值为 0,我如何优雅地返回 1.0 ?
我想要发生的是if
zv.sum(:volume)返回0.0,我希望它返回1.0。
因此,最好的方法是使用条件表达式:
sum = zv.sum(:volume).to_f
if sum == 0.0
1.0
else
sum
end
Run Code Online (Sandbox Code Playgroud)
如果你想“优化”这个,你可以将转换移动到浮动到表达式的最边缘:
sum = zv.sum(:volume)
if sum == 0
1
else
sum
end.to_f
Run Code Online (Sandbox Code Playgroud)
[注意,这假设 的值zv.sum(:volume)将是一个数字,而不是类似nil或代表数字的字符串。如果可以保证,同样的转换也可以应用于以下每个示例。]
在 Ruby 中总是可以轻松实现在 1 行中做某事的要求,因为换行符始终是可选的。例如:
sum = zv.sum(:volume).to_f; if sum == 0.0 then 1.0 else sum end
Run Code Online (Sandbox Code Playgroud)
或者,如果您想避免使用关键字:
sum = zv.sum(:volume).to_f; if sum == 0.0; 1.0 else sum end
Run Code Online (Sandbox Code Playgroud)
还有条件运算符,但就我个人而言,我认为它不能(更好)由条件表达式提供服务:
sum = zv.sum(:volume).to_f; sum == 0.0 ? 1.0 : sum
Run Code Online (Sandbox Code Playgroud)
如果你想要一个单一的表达式,你可以将变量赋值内联到条件中:
if (sum = zv.sum(:volume).to_f) == 0.0
1.0
else
sum
end
Run Code Online (Sandbox Code Playgroud)
当然,您可以将两者结合起来:
if (sum = zv.sum(:volume).to_f) == 0.0 then 1.0 else sum end
Run Code Online (Sandbox Code Playgroud)
并避免关键字:
if (sum = zv.sum(:volume).to_f) == 0.0; 1.0 else sum end
Run Code Online (Sandbox Code Playgroud)
并使用(仍然无用的)条件运算符:
(sum = zv.sum(:volume).to_f) == 0.0 ? 1.0 : sum
Run Code Online (Sandbox Code Playgroud)
如果你不介意一些稍微复杂的非本地控制流,你可以这样做:
zv.sum(:volume).to_f.tap {|sum| break 1.0 if sum == 0.0 }
Run Code Online (Sandbox Code Playgroud)
拉出浮点转换:
zv.sum(:volume).tap {|sum| break 1 if sum == 0 }.to_f
Run Code Online (Sandbox Code Playgroud)
此外,如果您知道有关总和的一些特殊情况,例如,如果您知道总和总是恰好为 0 或大于 1,那么您可以利用这些额外知识,并可能执行以下操作:
[1.0, zv.sum(:volume).to_f].max
Run Code Online (Sandbox Code Playgroud)
拉出浮点转换:
[1, zv.sum(:volume)].max.to_f
Run Code Online (Sandbox Code Playgroud)
但是,请注意,这些都不像第一个版本那样可读和清晰。
另外,请注意您问题中的描述和问题中的代码不匹配,因为代码不符合您在问题中描述的内容。
您可以使用nonzero?将零视为假值:
zv.sum(:volume).to_f.nonzero? || 1.0
Run Code Online (Sandbox Code Playgroud)
或者:
(zv.sum(:volume).nonzero? || 1).to_f
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
69 次 |
| 最近记录: |