以下、タブは全角半角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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PHPの構文で間違えが分からない
-
Excel VBAでフィルター後の対象...
-
phpでforeachの中にforeachがあ...
-
forを使わずにforeach文のみで...
-
php 省略可能な引数配列を持つ...
-
3つの連想配列を交互に代入し...
-
マッチング処理(1:N)
-
割り切れなくなるまで分割して...
-
配列をループでたくさん宣言し...
-
配列の要素(value)に、変数を...
-
stdClass Objectを連想配列のよ...
-
STLのvectorで作った配列をメン...
-
PHPでCSVの一部の行を編集したい
-
pg_copy_fromの使い方について...
-
PHPのカッコ[ ]の使い方について
-
Smarty の演算方法
-
csvの内容を行単位で削除したい
-
String だと「 ByRef引数の型が...
-
多次元配列のオーソドックスな...
-
複数行のデータのPOST処理に関して
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
pdfファイルの複数添付 引数の型
-
VB.NET で 二次元のハッシュは...
-
phpでforeachの中にforeachがあ...
-
マッチング処理(1:N)
-
Excel VBAでフィルター後の対象...
-
3つの連想配列を交互に代入し...
-
PHPで連想配列のプルダウンメニ...
-
PHPで変数名にハイフンを使うに...
-
PHP、{}記号の意味
-
ftokが動かない?
-
Delphi XEの警告文を消したい
-
foreachとかの勝手な省略?
-
配列からプルダウン用のHTMLを生成
-
PHPの構文で間違えが分からない
-
php 省略可能な引数配列を持つ...
-
foreachで上限回数指定方法また...
-
重複確認
-
Ruby 2次元のハッシュ
-
php mysql INSERT
-
foreachで配列を、左から縦3列...
おすすめ情報