以下、タブは全角半角4つに変換しています。
<?php
$arrWBS = array("1", "1.1", "1.1.1", "1.2",
"1.2.1","1.2.1.1","1.2.1.2","1.2.1.3","1.2.1.3.1","1.2.3", "1.3", "1.4", "1.
5","1.5.1");
$rootWBS = "1";
のような配列(配列はソートされています)と文字列があり、
それをもとに、
getWBSHtml($arrWBS,$rootWBS);関数なるものをつくり、
上の例($rootWBS = "1";)だと以下のようなHTMLをはき出したいと思っています。
<ul>
<li>1.1
<ul>
<li>1.1.1</li>
</ul>
</li>
<li>1.2
<ul>
<li>1.2.1
<ul>
<li>1.2.1.1</li>
<li>1.2.1.2</li>
<li>1.2.1.3</li>
<ul>
<li>1.2.1.3.1</li>
</ul>
</ul>
</li>
<li>1.2.3</li>
</ul>
<li>1.3</li>
<li>1.4</li>
<li>1.5
<ul>
<li>1.5.1</li>
</ul>
</li>
</li>
</ul>
===========================
そして、
$rootWBS = "1.2";だとすると、
<ul>
<li>1.2.1
<ul>
<li>1.2.1.1</li>
<li>1.2.1.2</li>
<li>1.2.1.3</li>
<ul>
<li>1.2.1.3.1</li>
</ul>
</ul>
</li>
<li>1.2.3</li>
</ul>
となるHTMLをはき出したくおもっています。
(できれば整形したかたちで)
===========================
途中まで後述のように書いたのですが、完成せず、
また、$arrWBSを必要以上に走査して無駄な気がします。
どのようにすればこういったHTMLをはき出せるのでしょうか?
よろしくお願いします。
getWBSHtml($arrWBS,$rootWBS);
function getWBSHtml($arrWBS,$rootWBS){
foreach($arrWBS as $data){
if (preg_match("/^$rootWBS\.[^.]+$/",$data) > 0) {
print "<ul>\n";
print "<li>";
print $data;
getWBSHtml($arrWBS,$data);
print "</li>\n";
print "</ul>\n";
}
}
}
?>
No.3ベストアンサー
- 回答日時:
配列の各要素ごとに次のような連想配列を作成します。
Array
(
[1] => Array
(
[0] => 1.1
[1] => 1.2
[2] => 1.3
[3] => 1.4
[4] => 1.5
)
[1.1] => Array
(
[0] => 1.1.1
)
[1.1.1] => Array
(
)
[1.2] => Array
(
[0] => 1.2.1
[1] => 1.2.3
)
[1.2.1] => Array
(
[0] => 1.2.1.1
[1] => 1.2.1.2
[2] => 1.2.1.3
)
[1.2.1.1] => Array
(
)
[1.2.1.2] => Array
(
)
[1.2.1.3] => Array
(
[0] => 1.2.1.3.1
)
[1.2.1.3.1] => Array
(
)
[1.2.3] => Array
(
)
[1.3] => Array
(
)
[1.4] => Array
(
)
[1.5] => Array
(
[0] => 1.5.1
)
[1.5.1] => Array
(
)
)
この配列を再帰的に処理すればOKです。全体はこんな感じです。
<?php
$arrWBS = array("1", "1.1", "1.1.1", "1.2",
"1.2.1","1.2.1.1","1.2.1.2","1.2.1.3","1.2.1.3.1","1.2.3", "1.3", "1.4", "1.5","1.5.1");
$rootWBS = "1";
// 連想配列の作成
$wbs_tree = array();
foreach($arrWBS as $data) {
$wbs_tree[$data] = array();
if (preg_match("/^(.*)\.[^.]+$/", $data, $matches) > 0) {
if(array_key_exists($matches[1], $wbs_tree)) {
array_push($wbs_tree[$matches[1]], $data);
}
}
}
// HTMLタグの作成
function getWBSHtml($datas, $indent, $wbs_tree) {
print(str_repeat(' ', $indent) . "<ul>\n");
foreach($datas as $name) {
print(str_repeat(' ', $indent+2) . "<li>");
print($name);
if (count($wbs_tree[$name]) > 0) {
print("\n");
getWBSHtml($wbs_tree[$name], $indent+4, $wbs_tree);
print(str_repeat(' ', $indent+2) . "</li>\n");
}
else {
print("</li>\n");
}
}
print(str_repeat(' ', $indent) . "</ul>\n");
}
// 実行
getWBSHtml($wbs_tree[$rootWBS], 0, $wbs_tree);
?>
No.4
- 回答日時:
<li>の終了タグは省略可なので、閉じなくても良いなら再帰処理すれば楽です。
ただしXHTMLだとアウト…。function getWBSHtml($arrWBS,$rootWBS){
//必要な分だけ配列に
$arr = preg_grep("/^$rootWBS\.(\d+)/",$arrWBS);
echo "<ul>\n";
$ch = $flag = '';
foreach($arr as $val){
//更に下層があれば、重複判定flagつけて再帰。
if(preg_match("/^$rootWBS\.(\d+)\.(\d)/",$val,$arg)){
$ch = "$rootWBS.{$arg[1]}";
if($flag !== $ch){ $flag = $ch; getWBSHtml($arr,$ch);}
//それ以外なら出力
}else{
echo "<li>$val\n";
}
}
echo "</ul>\n";
return;
}
No.2
- 回答日時:
前後関係だけを見て処理するならこんな感じ。
ただし相関関係があっているかは検証しないので微妙ですね
<?PHP
$arrWBS = array("1", "1.1", "1.1.1", "1.2","1.2.1","1.2.1.1","1.2.1.2","1.2.1.3","1.2.1.3.1","1.2.3", "1.3", "1.4", "1.5","1.5.1");
$space="\t";
foreach($arrWBS as $key=>$val){
$prev_num=$key==0?0:count(explode(".",$arrWBS[$key-1]));
$this_num=count(explode(".",$val));
$next_num=count($arrWBS)<=$key+1?0:count(explode(".",$arrWBS[$key+1]));
if($prev_num < $this_num){
$str.=str_repeat($space,$this_num -1);
$str.="<ul>\n";
}
$str.=str_repeat($space,$this_num);
$str.="<li>";
$str.=$val;
if($this_num == $next_num) $str.="</li>";
if($this_num >$next_num){
for($i=0;$i<$this_num -$next_num ;$i++){
if($i>0){
$str.="\n";
$str.=str_repeat($space,$this_num -$i);
}
$str.="</li>\n";
$str.=str_repeat($space,$this_num -1 -$i);
$str.="</ul>";
}
}
$str.="\n";
}
print "<pre>\n";
print htmlspecialchars($str);
print "</pre>\n";
print ($str);
?>
No.1
- 回答日時:
値が数字だけだと抽象的すぎて何をしたいのか解り辛いけど…。
関数の記述はこの際置いておいて、配列を多次元の連想配列にした方が処理しやすい様な気がします。
で、変数の $rootWBS には、その時々に応じて必要な連想配列のキー名を代入して、関数側から呼び出して処理する様にすれば割とスマートな感じになるんじゃないのかなあと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP アコーディオンPHPが上手くいかない 3 2022/07/15 16:29
- PHP style.cssのjQuery条件付きcssが機能しない 4 2022/07/17 18:27
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- その他(プログラミング・Web制作) どうしてもエラーが解決できません。 1 2022/07/23 04:32
- JavaScript html5に変えるとスライドショーが消えてしまった。 3 2022/03/26 19:53
- PHP SQLとPHPの連結方法がわからないのでアドバイスお願い致します 1 2022/07/12 12:16
- HTML・CSS display flex の使い方 1 2022/04/25 19:13
- HTML・CSS インラインブロックの中のテキストを上下中央に合わせたい 1 2022/12/24 17:46
- HTML・CSS htmlについて質問です! 写真のように写真の部分が?になってしまいます。 ファイルもしっかり選べて 1 2023/07/09 21:17
- HTML・CSS HTML & CSS 縦ボックス内の文字の左右センタリング 3 2023/03/25 04:23
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
マッチング処理(1:N)
-
$_POST受信で必要項目のみを結...
-
多次元配列を、1次元の配列にす...
-
ラジオボタンをランダムに表示...
-
日付、時間の2段階でソート
-
特定の文からメールアドレスの...
-
別ファイルの構造体の値を読み...
-
foreachのなかで次のキーを参照...
-
プルダウンメニューにDBの内容...
-
行数が30万件ほどあるCSVから、...
-
チェックボックス複数選択 mys...
-
読み(あ行~わ行)ごとに分け...
-
ファイルの逆読みってできますか?
-
String だと「 ByRef引数の型が...
-
CArrayの要素としてCStringArra...
-
$_SESSIONに二次元配列を使える...
-
配列を回すとき、最後の要素だ...
-
file_existsでファイル名の部分...
-
verilogで、配列の一部をタスク...
-
ネストが深い時のforeachはどう...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
smartyのforeachの使い方
-
マッチング処理(1:N)
-
foreachで上限回数指定方法また...
-
多次元配列を、1次元の配列にす...
-
foreachの間にテーブルの<TR>を...
-
PHP、{}記号の意味
-
VB.NET で 二次元のハッシュは...
-
$_POST受信で必要項目のみを結...
-
3つの連想配列を交互に代入し...
-
PHP:ツリー構造をulとli要素に...
-
foreachで配列を、左から縦3列...
-
PHPの構文で間違えが分からない
-
PHPで連想配列のプルダウンメニ...
-
添え字が全て文字列のPHPの多次...
-
テーブルデータ表示
-
Smartyでインクリメント
-
PHPで変数名にハイフンを使うに...
-
POSTで渡されるデータの数がわ...
-
Delphi XEの警告文を消したい
-
配列の要素の値をループ中に変...
おすすめ情報