Создание вложенного списка из многомерного массива
У меня есть массив в PHP, который выглядит так:
array (
[0] => array (
[id] => 1
[title] => "Title 1"
[parent_id] => NULL
[depth] => 0
)
[1] => array (
[id] => 2
[title] => "Title 2"
[parent_id] => NULL
[depth] => 0
)
[2] => array (
[id] => 3
[title] => "Title 3"
[parent_id] => 2
[depth] => 1
)
[3] => array (
[id] => 4
[title] => "Title 4"
[parent_id] => 2
[depth] => 1
)
[4] => array (
[id] => 5
[title] => "Title 5"
[parent_id] => NULL
[depth] => 0
)
[5] => array (
[id] => 6
[title] => "Title 6"
[parent_id] => 4
[depth] => 2
)
)
Что я хочу сделать, это перебрать этот массив и создать вложенный в него список <ol>
. Результат должен выглядеть так:
<ol>
<li>Title 1</li> // id = 1
<li>Title 2</li> // id = 2
<ol>
<li>Title 3</li> // id = 3 -> parent_id = 2
<li>Title 4</li> // id = 4 -> parent_id = 2
<ol>
<li>Title 6</li> // id = 6 -> parent_id = 4
</ol>
</ol>
<li>Title 5</li> // id = 5
</ol>
Я пытаюсь думать о том, как я могу это сделать. Но до сих пор каждая попытка не удалась...
Кто-нибудь знает, как я могу создать такой вложенный <ol>
список из такого массива?
Обратите внимание, что я не контролирую данные. Я просто обращаюсь к API и возвращает данные json, которые я конвертирую в массив. И массив выглядит точно так же, как я описал.
Ответы
Ответ 1
Вы должны использовать рекурсию:
Сначала массив в синтаксисе "php":
<?php
$a=array (
'0' => array (
'id' => 1,
'title' => "Title 1",
'parent_id' => 'NULL',
'depth' => 0
),
'1' => array (
'id' => 2,
'title' => "Title 2",
'parent_id' => 'NULL',
'depth' => 0
),
'2' => array (
'id' => 3,
'title' => "Title 3",
'parent_id' => 2,
'depth' => 1
),
'3' => array (
'id' => 4,
'title' => "Title 4",
'parent_id' => 2,
'depth' => 1
),
'4' => array (
'id' => 5,
'title' => "Title 5",
'parent_id' => 'NULL',
'depth' => 0
),
'5' => array (
'id' => 6,
'title' => "Title 6",
'parent_id' => 4,
'depth' => 0
)
);
Здесь код:
$level = 'NULL';
function r( $a, $level) {
$r = "<ol>";
foreach ( $a as $i ) {
if ($i['parent_id'] == $level ) {
$r = $r . "<li>" . $i['title'] . r( $a, $i['id'] ) . "</li>";
}
}
$r = $r . "</ol>";
return $r;
}
print r( $a, $level );
?>
Результаты :
<ol><li>Title 1<ol></ol></li><li>Title 2<ol><li>Title 3<ol>
</ol></li><li>Title 4<ol><li>Title 6<ol></ol></li></ol></li></ol></li><li>Title 5
<ol></ol></li></ol>
- Заголовок 1\n
- Заголовок 2\n
- Заголовок 3\n
- Заголовок 4\n
- Заголовок 6\n
- Заголовок 5\n
ИЗМЕНИТЬ ПОСЛЕ ПРОВЕРКИ КАК РЕШЕНИЕ
Чтобы избежать пустых листов:
function r( $a, $level) {
$r = '' ;
foreach ( $a as $i ) {
if ($i['parent_id'] == $level ) {
$r = $r . "<li>" . $i['title'] . r( $a, $i['id'] ) . "</li>";
}
}
return ($r==''?'':"<ol>". $r . "</ol>");
}
Ответ 2
Вы можете попробовать следующее
$array = array (
"0" => array (
"id" => 1,
"title" => "Title 1",
"parent_id" => NULL,
"depth" => 0
),
"1" => array (
"id" => 2,
"title" => "Title 2",
"parent_id" => NULL,
"depth" => 0
),
"2" => array (
"id" => 3,
"title" => "Title 3",
"parent_id" => 2,
"depth" => 1
),
"3" => array (
"id" => 4,
"title" => "Title 4",
"parent_id" => 2,
"depth" => 1
),
"4" => array (
"id" => 5,
"title" => "Title 5",
"parent_id" => NULL,
"depth" => 0
),
"5" => array (
"id" => 6,
"title" => "Title 6",
"parent_id" => 4,
"depth" => 0
)
);
echo(make($array));
Выход
<ol>
<li>Title 1</li>
<li>Title 2</li>
<ol>
<li>Title 3</li>
<li>Title 4</li>
<ol>
<li>Title 6</li>
</ol>
</ol>
<li>Title 5</li>
</ol>
Используемая функция
function make(array $array, $no = 0) {
$child = hasChildren($array, $no);
if (empty($child))
return "";
$content = "<ol>\n";
foreach ( $child as $value ) {
$content .= sprintf("\t<li>%s</li>\n", $value['title']);
$content .= make($array, $value['id']);
}
$content .= "</ol>\n";
return $content;
}
function hasChildren($array, $id) {
return array_filter($array, function ($var) use($id) {
return $var['parent_id'] == $id;
});
}
Смотрите Live Demo
Ответ 3
Следующий массив:
Array
(
[0] => Content
[1] => Array
(
[0] => International
[1] => Array
(
[0] => Mexico
[1] => Array
(
[0] => Tamaulipas
)
[2] => USA
)
)
)
С помощью этой функции:
function r($element) {
foreach ($element as $value) {
if (!is_array($value)) {
echo "<li>";
echo $value;
} else {
echo "<ul>";
r($value);
echo "</li>";
echo "</ul>";
}
}
}
PHP-код:
echo "<ul>";
r($array);
echo "</ul>";
Возврат:
<ul>
<li>Public</li>
<li>User</li>
<li>Content
<ul>
<li>International
<ul>
<li>Mexico
<ul>
<li>Tamaulipas</li>
</ul>
</li>
<li>USA</li>
</ul>
</li>
</ul>
</li>
</ul>