Рекурсия с анонимной функцией
Возможные дубликаты:
JavaScript: рекурсивная анонимная функция?
Анонимные рекурсивные функции PHP
Мне было интересно... Можно ли сделать рекурсию с анонимной функцией?
Вот один пример: мне нужно получить строку из шести символов, которая может содержать только цифры и пробелы. Единственные правила в том, что он не может начинаться или заканчиваться пробелами. Мы проверяем это и, если это происходит, просто вызываем рекурсию для той же анонимной функции. Только как!?
function() {
$chars = range(0, 9);
$chars[] = ' ';
length = 6;
$count = count($chars);
$string = '';
for ($i = 0; $i < $length; ++$i) {
$string .= $chars[mt_rand(0, $count - 1)];
}
$string = trim($string);
if (strlen($string) !== $length) { // There were spaces in front or end of the string. Shit!
// Do recursion.
}
return $string;
}
4 ответа
Да, но я бы не советовал, потому что это немного сложно;)
Первая возможность:
<?php
$some_var1="1";
$some_var2="2";
function($param1, $param2) use ($some_var1, $some_var2)
{
call_user_func(__FUNCTION__, $other_param1, $other_param2);
}
?>
Другой:
<?php
$recursive = function () use (&$recursive){
// The function is now available as $recursive
}
?>
Примеры взяты с http://php.net/
Ответ сложен, но не невозможен. Мне понадобилось несколько минут, чтобы понять. Сначала мы должны определить вспомогательную функцию с именем $combinator().
Решение вашей проблемы:
$combinator(
function($self) { function() use (&$self) {
$chars = range(0, 9);
$chars[] = ' ';
length = 6;
$count = count($chars);
$string = '';
for ($i = 0; $i < $length; ++$i) {
$string .= $chars[mt_rand(0, $count - 1)];
}
$string = trim($string);
if (strlen($string) !== $length) {
return $self();
}
return $string;
} }
);
Определение $combinator():
$combinator = function($principle)
{
(function($transept) use (&$principle)
{
$principle(
function($arguments) use (&$transept)
{
call_user_func_array($transept($transept), $arguments));
}
);
})
(function($transept) use (&$principle)
{
$principle(
function($arguments)
{
call_user_func_array($transept($transept), $arguments);
}
);
});
}
Гораздо более разумный способ сделать то же самое. Требуется только одна петля.
$chars = array_merge(range(0, 9), array(' '));
$string = mt_rand(0, 9);
for ($i = 1; $i <= 4; $i++) {
$string .= $chars[array_rand($chars)];
}
$string .= mt_rand(0, 9);
Извините за обход актуального вопроса, хотя.
Использовать goto
function() {
start:
$chars = range(0, 9);
$chars[] = ' ';
length = 6;
$count = count($chars);
$string = '';
for ($i = 0; $i < $length; ++$i) {
$string .= $chars[mt_rand(0, $count - 1)];
}
$string = trim($string);
if (strlen($string) !== $length) { // There were spaces in front or end of the string. Shit!
goto start;
}
return $string;
Но это не лучшая идея использовать goto.