Иерархический массив PHP - Родители и дети
Я использую PHP и mySQL с Idiorm. Это может быть не актуально.
Мой массив PHP
- Это отношения между родителями и детьми.
- 0 является родительским корнем.
- Пример. Корневой родительский 0 имеет дочерний элемент 33, у которого есть дочерний элемент 27, который имеет
ребенок 71.
Эта структура массива может быть изменена, если это необходимо для решения проблемы.
array (
33 =>
array (
0 => '27',
1 => '41',
),
27 =>
array (
0 => '64',
1 => '71',
),
0 =>
array (
0 => '28',
1 => '29',
2 => '33',
),
)
Мой иерархический результат
Что-то вроде этого, но как массив...
0 =>
28
29
33
27 =>
64
71
41
Информация
- Глубина не определена и может быть неограниченной. Я попробовал foreach, но это может быть не так.
Мои собственные мысли
- Некоторая рекурсивная функция?
- Некоторые из циклов?
Я попробовал оба из вышеперечисленного, просто получил беспорядок. Это просто.
Ответы
Ответ 1
Предложение от @deceze сработало. Однако входной массив должен изменить litte, как это...
$rows = array(
array(
'id' => 33,
'parent_id' => 0,
),
array(
'id' => 34,
'parent_id' => 0,
),
array(
'id' => 27,
'parent_id' => 33,
),
array(
'id' => 17,
'parent_id' => 27,
),
);
Из fooobar.com/questions/87443/...:
function buildTree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parentId) {
$children = buildTree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
$tree = buildTree($rows);
print_r( $tree );
Ответ 2
Я добавил в @Jens Törnell ответы, чтобы включить определение параметров имени столбца parent_id, имени ключа дочернего массива, а также имени столбца для id.
/**
* function buildTree
* @param array $elements
* @param array $options['parent_id_column_name', 'children_key_name', 'id_column_name']
* @param int $parentId
* @return array
*/
function buildTree(array $elements, $options = [
'parent_id_column_name' => 'parent_id',
'children_key_name' => 'children',
'id_column_name' => 'id'], $parentId = 0)
{
$branch = array();
foreach ($elements as $element) {
if ($element[$options['parent_id_column_name']] == $parentId) {
$children = buildTree($elements, $options, $element[$options['id_column_name']]);
if ($children) {
$element[$options['children_key_name']] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
Поскольку функциональность довольно универсальная, мне удалось использовать указанную выше функцию в большинстве моих проектов.
Ответ 3
отличный ответ от @Jens Törnell, просто хотел добавить небольшое усовершенствование, которое, если ваш parent_id и id на самом деле являются строкой вместо числа, тогда выше метод завершится неудачно и после создания дочернего массива он снова создаст эти дочерние массивы как отдельный индивидуальный массив. Чтобы исправить это, вы должны сделать тройную равную проверку и путем сопоставления типа данных переменной i.e(string).
Идентификаторы на основе строк и Parent_id в массиве
function buildTree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ((string)$element['parent_id'] === (string)$parentId) {
$children = buildTree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
дополнительно, если кто-то захочет, он может добавить третий параметр для работы, чтобы динамически указывать тип данных переменных i.e function buildTree(array $elements, $parentId = 0, $datatype='string')
, но тогда вам придется брать любую другую ошибку.
надеюсь, что это поможет кому-то!