如何重构以下代码以避免重复?
r = @lots.fetch @lots.keys.sample
until (neighbours r)
r = @lots.fetch @lots.keys.sample
end
我基本上有一个随机挑选的新r
对象,我需要选择r
,直到所选对象不响应某些条件(neighbours r
)。我怎样才能重构它以避免重复获得r并持续到达条件?感谢
答案 0 :(得分:4)
begin
r = @lots.fetch @lots.keys.sample
end until neighbours r
请注意,如果条件neighbours
不太可能,此类代码很容易导致长时间运行(甚至无限)循环。在这种情况下,请确保在Michael Kohl's answer中完成一次检查每个元素。
答案 1 :(得分:2)
就个人而言,我会将@lots
改组(如果需要,将其转换为双元素数组),然后像这样使用take_while:
>> h = {:a => 1, :b => 2, :c => 3} #=> {:a=>1, :b=>2, :c=>3}
>> h.to_a.shuffle.take_while { |k, v| v < 3 } #=> []
>> h.to_a.shuffle.take_while { |k, v| v < 3 } #=> [[:b, 2]]
>> h.to_a.shuffle.take_while { |k, v| v < 3 } #=> [[:a, 1]]
>> h.to_a.shuffle.take_while { |k, v| v < 3 } #=> [[:b, 2], [:a, 1]]
如果您需要再次将结果作为哈希,只需在其上调用Hash[]
:
>> Hash[h.to_a.shuffle.take_while { |k, v| v < 3 }] #=> {:a=>1}
在你的情况下,采取的条件将类似于{ |k, v| !(neighbours v)}
。此外,如果您希望起始散列中的元素可重复,则必须使用其他内容而不是shuffle
。