Преобразование массива. Рекурсия.

Damir

Новичок
Привет всем. Мне нужна помощь с рекурсией. Мне необходимо преобразовать массив array(Entry1 => array(Entry2 => array(Entry3 => "Boo !")) в строку "Entry[Entry2][Entry3]". Прошу помощи :)
 

Damir

Новичок
Забавы ради :) Есть необходимость в таком преобразовании)
 

Фанат

oncle terrible
Команда форума
очень показательный, кстати, ответ.
Наглядно показывающий, что у любой задачи может быть больше одного решения, и зависят они от контекста.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Его теперь как и Чушкина надо загнобить за этот ответ :)
 

Damir

Новичок
Очень умный, кстати, ответ.

Я считаю что контекст в данном вопросе не важен вовсе. Если же все таки вам очень интересно где это может применяться - я расскажу.
Есть конструктор форм. В нем можно строить различного рода поля. На примере тестового поля.
Если мы укажем "код" поля например "Declarant[Governance][Name]". Тогда построится некоторый инпут:

PHP:
<input type="text" name="Declarant[Governance][Name]" />
При отправке на сервер, все преобразуется в

PHP:
array("Declarant" => array("Governance" => array("Name")))
Но конструктор знает только то что его поле называется Declarant[Governance][Name]. Именно для того чтобы вновь заполнить конструктор данными - необходимо такое преобразование.
 

Вурдалак

Продвинутый новичок
Изначально вопрос не имел какого-то смысла, потому что преобразование неодназначное.
PHP:
$a = array("Declarant" => array("Governance" => array("Name" => "Tommy", "LastName" => "Vercetti")));
... и что в итоге?

А сама проблема надуманная, почему что если ввели поле с таким именем, то и должны ожидать массив.
 

Damir

Новичок
Метод который заполняет конструктор данными принимает массив, где ключем является код поля.
При ситуации, описанной выше, должно получаться так:


PHP:
array(
    "Declarant[Governance][Name]" => "Tommy",
    "Declarant[Governance][LastName]" => "Vercetti"
);
По-моему больше времени уходит на обсуждение постороннего вопроса, нежели на вопрос под темой, не ? :) Прошу помочь написать такое преобразование.
 

Damir

Новичок
Виноват, не точно описал преобразование, да.
Просто хотел до конца сделать сам, важен был лишь только сам момент преобразования массива в такую строку ключей.
Но раз требуется однозначность, тогда так.

На входе

PHP:
array("Declarant" => array("Governance" => array("Name" => "Вурдалак")));
На выходе

PHP:
array(
    "Declarant[Governance][Name]" => "Вурдалак"
);
 

Фанат

oncle terrible
Команда форума
но ведь нету же в реальности такого массива.
а есть тот, пример которого привёл Вурдалак.

а для такого линейного и рекурсия не нужна:
PHP:
$name = key($var);
while (is_array($var)) {
  $var   = reset($var);
  $name .="[".key($var)."]";
}
echo "$name: $var";
могу ошибаться, но как-то так
 

Damir

Новичок
Ваш вариант работает в случае

PHP:
$source = array("Declarant" => array("Governance" => array("Name" => "Vurdalack")));
а как быть в случае

PHP:
$source = array("Declarant" => array("Governance" => array("Name" => "Vurdalack", 'LastName' => "Juhidzoin")));
?

Вложенность может быть бесконечна. Именно поэтому нужна рекурсия. Рядом с "Declarant" могут стоять еще элементы. Суть состоит в том чтобы создать массив полных путей до каждого значения ключа массивов.
 

fixxxer

К.О.
Партнер клуба
ох

PHP:
function buildKey(array $path) {
    $result = reset($path);
    while ($token = next($path)) {
        $result .= '[' . $token . ']';
    }
    return $result;
}

function flatternRequest(array $source, array $path = array()) {
    $vars = array();
    foreach ($source as $k => $v) {
        $innerPath = $path;
        $innerPath[] = $k;
        if (is_array($v)) {
            $vars += flatternRequest($v, $innerPath);
        } else {
            $vars[ buildKey($innerPath) ] = $v;
        }
    }
    return $vars;
}
 

Damir

Новичок
ох

PHP:
function buildKey(array $path) {
    $result = reset($path);
    while ($token = next($path)) {
        $result .= '[' . $token . ']';
    }
    return $result;
}

function flatternRequest(array $source, array $path = array()) {
    $vars = array();
    foreach ($source as $k => $v) {
        $innerPath = $path;
        $innerPath[] = $k;
        if (is_array($v)) {
            $vars += flatternRequest($v, $innerPath);
        } else {
            $vars[ buildKey($innerPath) ] = $v;
        }
    }
    return $vars;
}
Черт подери, это работает :) Премного благодарен, мистер :)
 

Фанат

oncle terrible
Команда форума
Вложенность может быть бесконечна. Именно поэтому нужна рекурсия.
Не нужна.
Ты даже не читаешь, что тебе пишут.
Для того линейного массива, пример которого ты привёл, рекурсия не нужна. При любой глубине вложенности.
 

itprog

Cruftsman
Велосипедисты %)

PHP:
$data = array("Declarant" => array("Governance" => array("Name" => "Tommy", "LastName" => "Vercetti")));
$query_data = http_build_query($data);
preg_match_all('~(?:^|&)([^=]+)=~', $query_data, $matches);
var_dump(array_map('urldecode', $matches[1]));
 
  • Like
Реакции: AmdY

Фанат

oncle terrible
Команда форума
флоппик
Что именно я не прочёл? сообщение Вурдалака про множественность элементов массива?
 
Сверху