我想在满足其中一个条件时停止循环,但这些条件是按顺序进行的(逐步),无法一次全部调用。
我需要检查条件,然后使用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_
是很长的一步,这使我的代码非常笨拙
答案 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