人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPで質問です。次のarrayのリストを
$list= array(
0=>array('pid'=>'','name'=>'aaa'),
1=>array('pid'=>'0','name'=>'bbb'),
2=>array('pid'=>'3','name'=>'ccc'),
3=>array('pid'=>'4','name'=>'ddd'),
4=>array('pid'=>'1','name'=>'eee'),
5=>array('pid'=>'2','name'=>'fff'),
6=>array('pid'=>'1','name'=>'ggg'),
7=>array('pid'=>'','name'=>'hhh'),
);

次の用に出力してカテゴリーを作りたいのですが
再帰でやってみたのですがうまくいきませんでした。
出力:

aaa
?bbb
| ?eee
| | ?ddd
| | ?ccc
| | ?fff
| ?ggg
?hhh

参考URLなどいらないので、
答えとなるソースを教えてください。
よろしくお願いします。

●質問者: chibitomo
●カテゴリ:コンピュータ 学習・教育
✍キーワード:?B ?D AAA CCC ddd
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● GEN111
●36ポイント ベストアンサー
<?php
$list = array(
 0=>array('pid'=>'','name'=>'aaa'),
 1=>array('pid'=>'0','name'=>'bbb'),
 2=>array('pid'=>'3','name'=>'ccc'),
 3=>array('pid'=>'4','name'=>'ddd'),
 4=>array('pid'=>'1','name'=>'eee'),
 5=>array('pid'=>'2','name'=>'fff'),
 6=>array('pid'=>'1','name'=>'ggg'),
 7=>array('pid'=>'','name'=>'hhh'),
 );

function show_categories($list) {
 foreach ($list as $key => $value) $list[$key] = array('id' => $key, 'pid' => ($value['pid'] == '' ? -1 : $value['pid']), 'name' => $value['name']) ;

 while ($list !== array()) {
 static $level = array('-1') ;
 static $branch = array() ;

 for(;;) {
 $cmp = '
if ($a["pid"] =='.end($level).' &amp;&amp; $b["pid"] != '.end($level).') return -1 ;
if ($b["pid"] =='.end($level).' &amp;&amp; $a["pid"] != '.end($level).') return 1 ;
if ($b["pid"] =='.end($level).' &amp;&amp; $a["pid"] == '.end($level).') ($a["name"] < $b["name"] ? -1 : 1) ;
if ($a["pid"] != $b["pid"]) return ((int)$a["pid"] > (int)$b["pid"] ? 1 : -1) ;
return ($a["name"] < $b["name"] ? -1 : 1) ;
' ;
 usort($list, create_function('$a, $b', $cmp)) ;
 $first = reset($list) ;
 if ($first['pid'] == end($level)) break ;
 array_pop($level) ;
 array_pop($branch) ;
 }

 $one = array_shift($list) ;
 echo implode($branch).($one['id'] != 0 ? '?' : '').$one['name']."\n" ;
 $next = reset($list) ;
 $branch[] = ($next['pid'] == end($level) ? '|' : ' ') ;
 $level[] = $one['id'] ;
 }
}

echo "<pre>" ;
show_categories($list) ;
echo "</pre>" ;
?>

もう少しすっきりできるかもしれませんが。

◎質問者からの返答

いちばんすっきりしました。

大変ありがとうございました!


2 ● worldtravel
●0ポイント

これだけではできない気がするのですが...

私の勘違いでできたらすいません。

もちろんポイント不要です。


bbbとhhhはaaaの下にありますが、何を判断基準にしているのでしょうか。

また、eeeやgggはなぜhhhの下ではなくbbbの下に来るのでしょうか。

◎質問者からの返答

質問を質問でかえすなよ・・・。


3 ● ぱこち
●27ポイント
$list= array(
0=>array('pid'=>'','name'=>'aaa'),
1=>array('pid'=>'0','name'=>'bbb'),
2=>array('pid'=>'3','name'=>'ccc'),
3=>array('pid'=>'4','name'=>'ddd'),
4=>array('pid'=>'1','name'=>'eee'),
5=>array('pid'=>'2','name'=>'fff'),
6=>array('pid'=>'1','name'=>'ggg'),
7=>array('pid'=>'','name'=>'hhh'),
);

$list_copy = $list;
$list_tree = search_child();
$nest_count = array();
$l_flag = array();
$list_text = make_tree($list_tree, 0);

#print_r($list_tree);
exit($list_text);

function search_child($pid = -2) {

global $list_copy;

$list_tree = array();

for ($i = 0; $i < count($list_copy); $i++) {

if (isset($list_copy[$i]['get'])) continue;
$i_pid = ($list_copy[$i]['pid'] === '') ? -1 : intval($list_copy[$i]['pid']);
$i_name = $list_copy[$i]['name'];

if ($i_pid == $pid + 1) {

$list_copy[$i]['get'] = true;
$list_tree[$i_name] = search_child($i_pid);

}


}

return($list_tree);

}

function make_tree($list_tree, $nest) {

global $nest_count, $l_flag;

$list_text = '';
if (isset($nest_count[$nest])) $nest_count[$nest] = 0;
if (isset($l_flag[$nest])) $l_flag[$nest] = false;

foreach ($list_tree as $name => $list_tree_c) {

$nest_count[$nest]++;
if ($nest_count[$nest] == count($list_tree)) $l_flag[$nest] = true;

for ($i = 0; $i < $nest; $i++) {

$list_text .= ($l_flag[$i]) ? ' ' : '┃';

}

$list_text .= "┗{$name}\n";

if (count($list_tree_c)) $list_text .= make_tree($list_tree_c, $nest + 1);

}

return($list_text);

}

出力がちょっと違っていますがやりたい事はこんな事でしょうか。

◎質問者からの返答

こんな感じです。

ありがとうございました!


4 ● takfjt
●27ポイント

例出力のhhhは間違っていると判断しました.

$list= array(

0=>array('pid'=>'','name'=>'aaa'),

1=>array('pid'=>'0','name'=>'bbb'),

2=>array('pid'=>'3','name'=>'ccc'),

3=>array('pid'=>'4','name'=>'ddd'),

4=>array('pid'=>'1','name'=>'eee'),

5=>array('pid'=>'2','name'=>'fff'),

6=>array('pid'=>'1','name'=>'ggg'),

7=>array('pid'=>'','name'=>'hhh'),

);

function show_tree($list, $pid, $bar)

{

$a = array();

for ($i = 0; $i < count($list); $i++) {

if ($list[$i]['pid'] == $pid) {

$list[$i]['id'] = $i;

array_push($a, $list[$i]);

}

}

array_push($bar, "| ");

for ($i = 0; $i < count($a); $i++) {

for ($j = 0; $j < count($bar) - 1; $j++) {

print "$bar[$j]";

}

if (count($bar) > 1) {

print "?";

}

print $a[$i]['name'];

print "\n";

if ($i == count($a) - 1) {

array_pop($bar);

array_push($bar, " ");

}

$id = $a[$i]['id'];

show_tree($list, "$id", $bar);

}

}

show_tree($list, '', array());

◎質問者からの返答

明快です。ありがとうございました!

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ