【问题标题】:Ruby: until a new object has some propertyRuby:直到新对象具有某些属性
【发布时间】:2012-01-09 13:39:45
【问题描述】:

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

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

我基本上有一个随机挑选的新r 对象,我需要挑选r 直到所选对象不响应某些标准(neighbours r)。如何重构它以避免重复获取 r 并继续获取它直到达到条件?谢谢

【问题讨论】:

标签: ruby


【解决方案1】:
begin
  r = @lots.fetch @lots.keys.sample
end until neighbours r

请注意,如果条件 neighbours 不太可能出现,此类代码很容易导致长时间运行(甚至无限)循环。在这种情况下,最好确保您只检查每个元素一次,就像在 Michael Kohl's answer 中所做的那样。

【讨论】:

    【解决方案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}
    

    在您的情况下,take while 的条件类似于{ |k, v| !(neighbours v)}。此外,如果您希望起始哈希中的元素可重复,则必须使用其他东西而不是 shuffle

    【讨论】:

    • 这特别好,如果条件 (neighbours) 不太可能 (+1)。否则,为了获得一些随机值而对内存中的整个散列进行改组可能是矫枉过正的。
    • 这只是 Ruby 中可用的收集方法的一个示例,由 OP 编写完全符合其要求的代码。如果take_while 不是正确的工具,请执行带有否定条件的drop_while 并在剩余集合上使用first。 OP 也没有提及哈希大小或内存限制,我总是更喜欢简单的代码而不是过早的优化。
    • 请注意,使用这种方法,满足条件的v/r之后是不可用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 2021-11-18
    • 2020-09-18
    • 2011-07-04
    • 2012-12-27
    • 1970-01-01
    相关资源
    最近更新 更多