如何在一行中写条件语句?轨道

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.

有没有办法将这个逻辑纳入同一行?

或者有没有办法让这句话更加重构?

Way*_*rad 8

更改li.weightli.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)


set*_*rgo 5

请注意,上述所有问题的答案是正确的你的目的,而是直接回答你的问题:

如何在一行中编写条件语句?轨道

您可以使用三元运算符.他们采取以下形式:

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#......)都有三元运算符.