我想说这个
self.preferred_amount * object.each{|li|li.variant}.collect{|li|li.weight}
唯一的问题是某些权重等于零。
在这种情况下,我想补充一点,如果它们相等,则将它们设为0。
有没有办法将这个逻辑合并到同一行?
或者有没有办法让这句话比它更重构?
答案 0 :(得分:8)
将li.weight
更改为li.weight || 0
||
是“短路或”运营商。如果它的左侧是真的(既不是假也不是零),它会返回左侧,否则它会返回右侧。
MRI> = 1.8.7中有一项功能可以让你做到这一点。而不是:
each{|li|li.variant}
你可以写
each(&:variant)
在1.8.7之前的Ruby版本中,需要backports gem才能获得此功能。
更好的是,将所有逻辑移到对象的类中,例如
class Whatever
def variant_weights
each(&:variant).collect{ |li| li.weight || 0}
end
end
并使用它:
self.preferred_amount * object.variant_weights
但请注意,将标量乘以数组是一个错误。如果你的意思是加权,那么:
class Whatever
def total_variant_weights
each(&:variant).collect{ |li| li.weight || 0}.inject(&:+)
end
end
并使用它:
self.preferred_amount * object.total_variant_weights
答案 1 :(得分:5)
请注意,上述所有答案都是正确,但是要直接回答您的问题:
如何在一行中编写条件语句?轨道
您可以使用三元运算符。他们采取以下形式:
assertion ? value_if_true : value_if_false
# if assertion is true, then value_if_true, otherwise, value_if_false
例如:
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' %>
就像我说的,上面的答案实际上就是你想要的特定操作(不是三元运算符在这种情况下不会工作)。我只是想让你更深入地了解一线人。
另请注意,这不是特定于Ruby的。大多数编程语言(包括Ruby,PHP,CF,AS,JAVA,C,C#......)都有三元运算符。
答案 2 :(得分:2)
仅|| 0
重量:
self.preferred_amount * object.each{|li|li.variant}.collect{|li|li.weight || 0}
答案 3 :(得分:2)
尝试
.collect{|li|li.weight || 0}
答案 4 :(得分:2)
每个似乎都是多余的。怎么样:
self.preferred_amount * object.collect { |o| o.variant.weight.to_i }
或者如果你真的想要加权:
self.preferred_amount * object.inject { |sum, o| sum + o.variant.weight.to_i }