Ruby 更改时重复。。。不再发生变化时停止,即稳定值

Ruby 更改时重复。。。不再发生变化时停止,即稳定值,ruby,algorithm,string,computer-science,Ruby,Algorithm,String,Computer Science,我想知道是否有一个很好的模式,或者更好的是一个特定的函数,它应用一个函数,直到它的结果不再有变化 url = "http://www.zzz.com/yyy/lt%255B1%255D.jpg" unescaped = unescape(url) while unescaped != url do url = unescaped unescaped = unescape(unescaped) end 虽然上面的代码基本上是ruby,但我认为它作为psudocode是可读的。unesca

我想知道是否有一个很好的模式,或者更好的是一个特定的函数,它应用一个函数,直到它的结果不再有变化

url = "http://www.zzz.com/yyy/lt%255B1%255D.jpg"
unescaped = unescape(url)
while unescaped != url do
  url = unescaped
  unescaped = unescape(unescaped)
end
虽然上面的代码基本上是ruby,但我认为它作为psudocode是可读的。unescaped的第一个设置是to,然后在发生更改时调用循环,这样unescaped变为,再次调用循环,因为再次发生更改,但这一次对unescape没有任何影响,因此url和unescaped变为相同,打破while循环

这段代码没有任何问题,比如说,我想知道是否有一种更合适的方式来表示它,或者是用psudocode形式,或者,对于我的具体情况,是用ruby


非常感谢您一如既往的帮助

您可以将其编写为递归函数,直到输入和输出匹配为止

operate_while_change (input) {

  output <= change(input)

  output <= operate_while_change(output) if output != input

  return output

}
改变时操作(输入){

输出根据macabail对我最初问题的回答,这里是ruby的递归解决方案:

def rec_unescape(url)
  url == (out = CGI::unescape(url)) ? out : rec_unescape(out)
end

将macabil&roja的合作转化为可重用的ruby方法:

#!/usr/bin/ruby1.8

module Kernel
  def while_changed
    result = :the_first_result_is_considered_a_change
    begin
      previous_result = result
      result = yield
    end until result == previous_result
  end
end

x = 0
while_changed do
  x += 1 if x < 4
  puts x
  x
end

# => 1
# => 2
# => 3
# => 4
# => 4
!/usr/bin/ruby1.8
模块内核
def,而_改变了
结果=:第一个结果被认为是变化
开始
上一个结果=结果
结果=产量
结束直到结果==上一个结果
结束
结束
x=0
当你改变时,你会做什么
如果x<4,则x+=1
放x
x
结束
# => 1
# => 2
# => 3
# => 4
# => 4

以上两个答案都很好。下面是一个常规函数,它返回所提供块的第一个重复输出:

def stabilize(input)
  input == (result = yield(input)) ? result : stabilize(result)
end

fully_escaped = stabilize(url) {|s| CGI::unescape(s)}
显然,此函数没有防止永远不会稳定到重复结果的块,但它确实允许一种简单的方法来传递几乎任何函数,包括取消跳过。

如果将unescape()包装到helper函数中,您自己的解决方案将重构成非常漂亮的东西,我认为:

def unescape2(url)
    return url, unescape(url)
end

url = "http://www.zzz.com/yyy/lt%255B1%255D.jpg"
o_url, url = unescape2(url) until o_url == url
或者我想你可以使用lambda函数:

url = "http://www.zzz.com/yyy/lt%255B1%255D.jpg"
o_url, url = lambda{|z| return z, unescape(z)} until o_url == url

无论你认为哪个读得更好。

我都喜欢。想知道是否有一种很好的方法在ruby中实现它!为最新的macabail干杯!对于ruby;递归实现:)def rec_unescape(url)url==(out=CGI::unescape(url))?out:rec_unescape(out)很高兴它帮助了你;这绝对是一个不错的结果。两者都是递归实现。你的更简洁,但他的(显然在正文中称自己)也是递归的。呵呵,是的,我知道。我想我的文章写得很糟糕!我喜欢:)我可能会尝试添加“最大深度”和“最小稳定性”这样我们就可以防止永远不稳定的值,也可以防止那些稳定性需要不止一次稳定迭代来验证真实稳定性的事件,从而防止人为稳定的值。