Повторите при изменении ... остановите, как только изменение больше не происходит, т.е. стабилизируйте значение - PullRequest
1 голос
/ 04 февраля 2010

Мне было интересно, есть ли хороший шаблон или, что еще лучше, особая функция, которая применяет функцию до тех пор, пока ее результат не перестанет изменяться.

url = "http://www.zzz.com/yyy/lt%255B1%255D.jpg"
unescaped = unescape(url)
while unescaped != url do
  url = unescaped
  unescaped = unescape(unescaped)
end

Хотя приведенный выше код в основном ruby, я думаю, что он достаточно читабелен как псевдокод. Первая настройка unescaped - это http://www.zzz.com/yyy/lt%5B1%5D.jpg,, затем цикл вызывается, поскольку произошли изменения, и поэтому unescaped становится http://www.zzz.com/yyy/lt[1].jpg, цикл Вызван снова, так как снова произошли изменения, но на этот раз нам нечего скрывать, и поэтому url и unescaped становятся такими же, прерывая цикл while.

В этом коде нет ничего плохого, мне кажется, мне интересно, есть ли более простой способ его представления, либо в форме псевдокода, либо, в моем конкретном случае, в ruby.

Очень ценю помощь, как всегда!

Ответы [ 5 ]

2 голосов
/ 04 февраля 2010

Основываясь на ответе macabail на мой оригинальный вопрос, вот рекурсивное решение для ruby:

def rec_unescape(url)
  url == (out = CGI::unescape(url)) ? out : rec_unescape(out)
end
1 голос
/ 04 февраля 2010

Вы можете написать это как рекурсивную функцию, которая повторяется до совпадения ввода и вывода.

operate_while_change (input) {

  output <= change(input)

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

  return output

}
0 голосов
/ 05 февраля 2010

Если вы оберните unescape () во вспомогательную функцию, ваше собственное решение превратится во что-то довольно симпатичное, я думаю:

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

Или, я думаю, вы можете использовать лямбда-функцию:

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

Что бы вы ни думали, читайте лучше.

0 голосов
/ 05 февраля 2010

Оба ответа выше хороши. Вот общая функция, которая возвращает первый повторный вывод предоставленного блока:

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

fully_escaped = stabilize(url) {|s| CGI::unescape(s)}

Очевидно, что эта функция не имеет защиты от блоков, которые никогда не стабилизируются до повторяющегося результата, но она позволяет простым способом обойти практически любую функцию, включая неэкранирование.

0 голосов
/ 05 февраля 2010

Превращение сотрудничества macabil & roja в рубиновый метод многократного использования:

#!/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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...