システムが出す配列とのことで、お困りのようなので、試しにやってみました。phpは何でもできます。
(その配列を出すシステムは微妙です)
ある程度のパターンは考えましたが、うまくいかないこともあると思います。
手続的に順次処理しているので、コメントを参考に修正すれば、まあ対応できるのではないでしょうか。
php
1<?php
2$arr =
3[
4 ["id" => "id1", "heading" => "heading2", "text" => "見出し2"],
5 ["id" => "id2", "heading" => "heading3", "text" => "見出し3"],
6 ["id" => "id3", "heading" => "heading2", "text" => "見出し2"],
7 ["id" => "id4", "heading" => "heading3", "text" => "見出し3"],
8 ["id" => "id5", "heading" => "heading4", "text" => "見出し4"],
9]; //質問の配列
10
11echo buildUL($arr, 0); //出力
12
13//アンカタグを作る
14function buildA($id, $text) {
15 return '<a href="#'.$id.'">'.$text.'</a>';
16}
17
18//liタグを作る
19function buildLIs($array, $depth = 0) { //連想配列の配列と、インデントの深さをもらう
20 if(count($array) === 1) { return buildLI($array[0], $depth);}
21 $open = '<li>';
22 $close = '</li>';
23 $indent = ' ';
24 $ret = '';
25 while(($cur = array_shift($array)) !== null) { //要素が尽きるまで、同一階層のli要素のループ
26 //配列の先頭を描画して
27 $ret .= str_repeat($indent, $depth).$open.PHP_EOL;
28 $ret .= str_repeat($indent, $depth + 1).buildA($cur["id"], $cur["text"]).PHP_EOL;
29 if(hasChild($cur, $array)) { //子階層を持っていたら、ループ中の配列から子供を飛ばして、子供の描画を移譲。
30 $children = pickChildren($cur, $array);
31 $array = array_slice($array, count($children));
32 $ret .= buildUL($children, $depth + 1);
33 }
34 //配列の先頭に対応する閉じタグ
35 $ret .= str_repeat($indent, $depth).$close.PHP_EOL;
36 }
37 return $ret;
38}
39
40//li要素が一個しかないときの整形のため
41function buildLI($item, $depth = 0) { //連想配列を受ける(配列の配列ではなくて)
42 $open = '<li>';
43 $close = '</li>';
44 $indent = ' ';
45
46 $ret = str_repeat($indent, $depth).$open;
47 $ret .= buildA($item["id"], $item["text"]);
48 $ret .= $close.PHP_EOL;
49 return $ret;
50}
51
52//ulタグを作る
53function buildUL($array, $depth = 0) {
54 $open = '<ul>';
55 $close = '</ul>';
56 $indent = ' ';
57
58 $ret = str_repeat($indent, $depth).$open.PHP_EOL;
59 $ret .= buildLIs($array, $depth + 1);
60 $ret .= str_repeat($indent, $depth).$close.PHP_EOL;
61 return $ret;
62}
63
64//$arrayの中に、$parentの子となるものが存在するか。
65function hasChild($parent, $array) {//$parentは連想配列、$arrayは連想配列の配列
66 return $parent["heading"] < $array[0]["heading"];
67}
68
69//$arrayの中の、$parentの子を取り出す。
70function pickChildren($parent, $array) {//$parentは連想配列、$arrayは連想配列の配列
71 $ret = [];
72 foreach($array as $item) {
73 if($parent["heading"] >= $item["heading"]) { //headingが自身と同じ以上だったら子でない
74 break;
75 }
76 $ret[] = $item;
77 }
78 return $ret;
79}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。