2016-05-17 11 views
0

私は以下のテーブル/ PHP配列を持っています。PHPは行の配列をツリー構造の連想配列に変換します

fileid | storage | parent | name | is_dir |  last_changed  | size | revision 
--------+---------+--------+------------+--------+----------------------------+-----------+---------- 
     1 |  1 |  | bunny.mov | f  | 2016-05-17 12:20:45.430934 | 514832018 |  103 
     2 |  1 |  | 10mb.bin | f  | 2016-05-17 12:24:11.291796 | 10000000 |  104 
     3 |  1 |  | 10mb.bin | f  | 2016-05-17 12:28:16.867 | 10000000 |  105 
     4 |  1 |  | bunny.mov | f  | 2016-05-17 12:34:42.191069 | 514832018 |  106 
     5 |  1 |  | miep2  | t  | 2016-05-17 12:38:09.286883 |  4096 |  107 
     6 |  1 |  5 | bunny.mov | f  | 2016-05-17 12:38:09.295631 | 514832018 |  107 
     7 |  1 |  | miep2  | t  | 2016-05-17 12:48:25.375968 |  4096 |  108 
     8 |  1 |  7 | bunany.mov | f  | 2016-05-17 12:48:25.384048 | 514832018 |  108 

このデータを連想配列で取得すると、ツリーのような構造を構築できます。 (いくつかの種類のファイルブラウザで、各ファイルにはユーザーが選択できるリビジョンのリストがあります)

これまでのところ、私は次のコードを持っています。

private function rebuildStructure($files, $parent) 
{ 
    $result = array(); 

    foreach ($files as $file){ 
     $entries = array(); 
     //get entries with $parent 
     foreach ($files as $entry_file){ 
      if ($entry_file->parent == $file->id){ 
       array_push($entries, $this->rebuildStructure($files, $entry_file->fileid)); 
      } 
     } 
     array_push($result, array(
      'name' => $file->name, 
      'entries' => $entries 
     )); 
    } 
    return $result; 
} 

しかし、これは機能しません(無限ループ)。私が間違っているアイデアは? 私は何かのラインに沿ってしたいと思います。

array(
    array('name' => 'miep2', 
      'entries' => array(...and repeat...) 
    ) 
) 

お勧めはありますか?ありがとうございました!

+0

メソッドのforループ内でこのメソッドを呼び出します。このメソッドは、実際には無限ループで終了します。また、あなたがそれを使用しないなら、あなたの関数に '$ parent'パラメータを与えているのです;) – Loek

答えて

1

このコードの目的は、ソリューションを最も簡単な方法で実装することです。これは効率的ではありません。

このaproachは、配列内のすべての要素のすべての子を見つけようとします。

private function rebuildStructure($files, $parent) 
{ 
    $result = array(); 

    foreach ($files as $file) { 
     // I'm searching for some childs, and I'm not one of them. 
     if (0 != $parent && $parent != $file->parent) continue; 

     // I'm a child and we are searching just for "parents" 
     if (!empty($file->parent) && 0 == $parent) continue; 

     $entries = array(); 

     // Next nesting level, search for children 
     array_push($entries, rebuildStructure($files, $file->fileid)); 

     array_push($result, array(
      'name' => $file->name, 
      'entries' => $entries 
     )); 
    } 

    return $result; 
} 
+0

これはすごくうまくいく、ありがとう@Miguel!あなたの意見では、より効率的な方法は何ですか? – Niels

+0

この問題で再帰を使用する必要はなく、アレイ上で何度も繰り返し処理する必要はありません。ただ1つのループでツリーを効率的に処理できます。 –

+0

あなたはそれがどれほど深いか分からないとしても? – Niels

0

私はこれを考え出しました。あなたが望むように動作するはずです。

private function rebuildStructure($files) 
{ 
    $result = array(); 

    foreach ($files as $file) 
    { 
     $entries = array(); 

     foreach ($files as $entry_file) 
     { 
      if ($entry_file->parent === $file->id) 
      { 
       $nestedArray = array(); 
       array_push($nestedArray, $entry_file); 
       array_push($entries, $nestedArray); 
      } 
     } 
     array_push($result, array(
      'name' => $file->name, 
      'entries' => $entries 
     )); 
    } 
    return $result; 
} 

// Call this function to get the tree structure 
public function getRebuildedStructure($files) 
{ 
    return rebuildStructure($files); 
} 
+0

元の問題は再帰を使うことになっていたようですが、この場合2レベルのネストは機能しません。 –