Tri*_*rip 1 ruby refactoring ruby-on-rails
我想说这个
self.preferred_amount * object.each{|li|li.variant}.collect{|li|li.weight}
Run Code Online (Sandbox Code Playgroud)
唯一的问题是某些权重等于零.
在这种情况下,我想补充一点,如果它们等于零,则使它们等于0.
有没有办法将这个逻辑纳入同一行?
或者有没有办法让这句话更加重构?
更改li.weight
到li.weight || 0
||
是"短路或"运营商.如果它的左侧是真的(既不是假也不是零),它会返回左侧,否则它会返回右侧.
MRI> = 1.8.7有一个功能可以让你做到这一点.代替:
each{|li|li.variant}
Run Code Online (Sandbox Code Playgroud)
你可以写
each(&:variant)
Run Code Online (Sandbox Code Playgroud)
在1.8.7之前的Ruby版本中,需要backports gem才能获得此功能.
更好的是,将所有逻辑移动到对象的类中,例如
class Whatever
def variant_weights
each(&:variant).collect{ |li| li.weight || 0}
end
end
Run Code Online (Sandbox Code Playgroud)
并使用它:
self.preferred_amount * object.variant_weights
Run Code Online (Sandbox Code Playgroud)
但是,请注意,将标量乘以数组是一个错误.如果你的意思是加权,那么:
class Whatever
def total_variant_weights
each(&:variant).collect{ |li| li.weight || 0}.inject(&:+)
end
end
Run Code Online (Sandbox Code Playgroud)
并使用它:
self.preferred_amount * object.total_variant_weights
Run Code Online (Sandbox Code Playgroud)
请注意,上述所有问题的答案是正确的你的目的,而是直接回答你的问题:
如何在一行中编写条件语句?轨道
您可以使用三元运算符.他们采取以下形式:
assertion ? value_if_true : value_if_false
# if assertion is true, then value_if_true, otherwise, value_if_false
Run Code Online (Sandbox Code Playgroud)
例如:
puts 4 < 5 ? 'you are on Earth' : 'you are on another planet'
<%= @user.is_admin? ? 'you can access this page' : 'you aren\'t allowed to be here' %>
Run Code Online (Sandbox Code Playgroud)
就像我说的,答案上面实际上是你想要的这个特殊的操作(不是三元运营商不会在这种情况下工作).我只是想让你更深入地了解一线人.
另请注意,这不是特定于Ruby的.大多数编程语言(包括Ruby,PHP,CF,AS,JAVA,C,C#......)都有三元运算符.