多条件循序渐进

时间:2019-01-17 04:02:41

标签: ruby

我想在满足其中一个条件时停止循环,但这些条件是按顺序进行的(逐步),无法一次全部调用。

我需要检查条件,然后使用next跳过循环。该代码在多种情况下看起来很难看。

array.each do |x|
          new_varible_1 = condition_1 ? func1(x) : func2(x)
          next if check_condtion_1   
          new_varible_2 = condition_2 ? func3(new_variable_1) : func4(new_variable_1)
          next if check_condtion_2 ## check_conditon_x include new_variable assigned
          new_varible_3 = condition_3 ? func5(new_variable_2) : func6(new_variable_1)
          next if check_condtion_3
          ## etc
    end

我想更优雅地重写它。可以采用动态方法进行编程吗?

  

更新:谢谢所有我的新手问题,但我修改了示例以更好地描述我的问题:实际上,它要求在每个步骤中分配新变量。如果check_condtion_不满意,我应该跳过下一步。实际上condition_function_是很长的一步,这使我的代码非常笨拙

2 个答案:

答案 0 :(得分:0)

只要尝试得出更多好的答案,
我认为一种方法是这样的:

array.each do |x, condition_| ## each element is [x, true] 
  (condition_ = false; next) if 
      x.nil? || x.respond_to?("string") || x+y[x] == 4
end

也不需要for

答案 1 :(得分:0)

@ kimmo-letho答案很好(第二部分实际修改了条件。

出于完整性考虑,我将添加一个更加惯用的版本,因为在注释中添加代码并不容易。

array.each do |item|
  x, _ = item
  case
  when x.nil?
    item[1] = false
  when x.respond_to?("string")
    item[1] = 'it is a string'
  end
end

另一方面,给人的印象是,您正在循环之前手动构建[x, true]的数组。如果您只需要打印(或退回)具有真实条件的物品,则可以做得更好:

# xs => [x1, x2, x3, ...]
# where your original array was [[x1, cond1], [x2, cond2], ...]
xs.reject do |x|
  x.nil? || x.respond_to?("string") || x+y[x] == 4
end

如果您已经有一些假病,并且想要保留前一个病:

# array => [[x1, cond1], [x2, cond2], ...]
array.map do |x, cond|
  [x, cond && !(x.nil? || x.respond_to?("string") || x+y[x] == 4)]
end