1

データベース主導のナビゲーションを構築していますが、データ構造を構築する方法について助けが必要です。私は再帰の経験があまりありませんが、これはおそらくこれがたどる道です。データベース テーブルには、id 列、parent_id 列、および label 列があります。メソッドを呼び出した結果、データ構造が得られます。私のデータ構造が次のようになる方法:

  • parent_id が 0 のレコードは、ルート要素と見なされます。
  • ルート要素 ID と等しい parent_id を含む要素の配列を保持する子が存在する場合、各ルート要素には子の配列が含まれます。
  • 子には、直接の子と等しいparent_idsを含む子配列が含まれる場合があります(これが再帰ポイントになります)
  • 0 以外の parent_id を含むレコードが存在する場合、子要素の配列に追加されます。

データ構造は次のようになります。

$data = array(
  'home' => array(    
      'id' => 1,
      'parent_id' => 0,
      'label' => 'Test',
      'children' => array(
          'immediatechild' => array(
              'id' => 2,
              'parent_id' => 1,
              'label' => 'Test1',
              'children' => array(
                 'grandchild' => array(
                     'id' => 3,
                     'parent_id' => 2,
                     'label' => 'Test12',
             ))
         ))
  )

);

ここに私が数分で思いついたものがあります。それは正しくありませんが、私が使いたいものであり、修正の助けが欲しいです。

<?php
// should i pass records and parent_id? anything else?
function buildNav($data,$parent_id=0)
{
   $finalData = array();
   // if is array than loop
   if(is_array($data)){
      foreach($data as $record){
          // not sure how/what to check here
        if(isset($record['parent_id']) && ($record['parent_id'] !== $parent_id){
            // what should i pass into the recursive call?            
            $finalData['children'][$record['label'][] = buildNav($record,$record['parent_id']);
         }
      }
    } else {
       $finalData[] = array(
        'id' => $data['id'],
        'parent_id' => $parent_id,
        'label' => $data['label'],         
     )
   } 
    return $finalData
}

助けてくれてありがとう!

4

1 に答える 1

2

最も簡単な解決策 (階層を示すために親 ID を FK として使用してリレーショナル表現に格納されたデータがあると仮定) は、ブルート フォースすることです。

 $start=array(
     array('parent_id'=>0, 'title'=>'Some root level node', 'id'=>100), 
     array('parent_id'=>0, 'title'=>'Other root level node', 'id'=>193),
     array('parent_id'=>100, 'title'=>'a child node', 'id'=>83),
     ....
 );
 // NB this method will work better if you sort the list by parent id

 $tree=get_children($start, 0);

 function get_children(&$arr, $parent)
 {
    static $out_index;
    $i=0;
    $out=array();
    foreach($arr as $k=>$node) {
       if ($node['parent_id']==$parent) {
         ++$i;
         $out[$out_index+$i]=$node;
         if (count($arr)>1) {
             $out[$out_index+$i]['children']=get_children($arr, $node['id']);
         }
         unset($arr[$k]);
    }
    $out_index+=$i;
    if ($i) {
      return $out;
    } else {
      return false;
    }
 }

しかし、より良い解決策は、データベース内のデータに隣接リスト モデルを使用することです。暫定的な解決策として、毎回解析するのではなく、ツリー配列をシリアル化してファイルにキャッシュすることをお勧めします。

于 2012-05-04T15:06:21.793 に答える