PHP — рекурсия многомерного массива

#php #arrays #recursion #multidimensional-array

#php #массивы #рекурсия #многомерный массив

Вопрос:

У меня есть проблема, я знаю, как ее решить, но не на 100% ясно, как будет выглядеть реализация.

Это приложение Symfony 3, но проблема заключается в чистом PHP, который включает в себя какую-то рекурсию.

У меня есть многомерный массив, который представляет мою вложенную форму и ошибки, которые необходимо отобразить в поле формы (этот бит я знаю, как это сделать).

Вот мой массив:

введите описание изображения здесь

Мне нужно рекурсивно перебирать дочерние fields элементы, и когда я дойду до конца узла, и он содержит message ключ (просто способ подтвердить, что я достиг ошибки), затем примените это к форме // apply to form here , а затем удалите этот индекс / узел, чтобы рекурсия больше не повторялась по этому маршруту?

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

Мой класс на нем стоит, но я могу сократить по крайней мере 50% от этого, если я могу просто следовать ключам массива:

http://laravel.io/bin/ok5n9

Любая помощь будет очень признательна 🙂

Комментарии:

1. Что вы пробовали до сих пор?

Ответ №1:

При циклическом просмотре вашего массива используйте цикл for, чтобы вы могли легко манипулировать индексами:

 for($i = 0; $i < count($fields); $i  ) {
    // You can use $fields[$i] here for the current item
}
 

Используя isset() , вы можете проверить message , существует ли ключ в fields массиве. Если это верно, используйте continue ключевое слово, чтобы пропустить текущий элемент и перейти к следующему.

Это будет выглядеть примерно так, вы можете изменить его в соответствии с вашими потребностями:

 for($i = 0; $i < count($fields); $i  ) {
    if (isset($fields[$i]['message')) {
        // error exists...
        continue;
    }

    // Delete the item from your array
    unset($fields[$i]);
}
 

Комментарии:

1. Это был бы код внутри рекурсивной функции, не так ли? Вам все равно пришлось бы вызывать себя снова, чтобы перейти к следующему слою? Также из любопытства , почему -1 ?

2. Я считаю - 1 , что это ошибка, так как это привело бы к пропуску последнего поля.

3. Это -1 потому count() , что функция 1 индексируется, но массивы в PHP 0 индексируются.

Ответ №2:

Это мое исправление. Я создал карту формы, которая состоит из количества полей, каждое из которых содержит дочерние массивы для пути к элементу и ошибке.

Затем я перебираю их и передаю их через mapViolation метод Symfonys SymfonyComponentFormExtensionValidatorViolationMapperViolationMapper .

Вот полный класс: https://gist.github.com/linxlad/3ec76c181f717fba532bf43484b7c970