Ruby:直到一个新对象有一些属性

时间:2011-11-30 09:47:32

标签: ruby

如何重构以下代码以避免重复?

  r = @lots.fetch @lots.keys.sample      
  until (neighbours r)
    r = @lots.fetch @lots.keys.sample
  end

我基本上有一个随机挑选的新r对象,我需要选择r,直到所选对象不响应某些条件(neighbours r)。我怎样才能重构它以避免重复获得r并持续到达条件?感谢

2 个答案:

答案 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