2010-04-05 5 views
1

나는 "parent_album_id"를 각 "앨범"에 할당하여 mysql에 무한대로 중첩 된 디렉토리 구조를 저장합니다 (상위 레벨에 있지 않는 한 parent_album_id가 없습니다)."parent_id"를 기반으로 다차원 배열로 배열

먼저 데이터베이스에서 모든 앨범의 배열을 가져 와서 각 앨범 키를 "id"(자동 증가 ID)로 변경합니다.

다음으로 앨범 배열을 다차원 배열로 재구성하여 각 앨범의 하위 앨범에 '어린이'를 저장하려고합니다. 나는 약간의 성공을했습니다. 다음 코드는 배열의 한 수준 아래로 내려 가면 잘 작동하지만 한 수준 이상으로 내려 가면 배열의 전체 구조가 손실됩니다. 이는 재귀 적으로 array_search_key를 호출 할 때 전체 배열을 전달하지 않고 검색하려는 다음 수준 만 전달하기 때문입니다.

배열을 재귀 적으로 검색 할 수 있지만 전체 다차원 배열의 앨범을 반환 할 수 있습니까?

foreach ($albums as &$album){ 
    if($album['parent_album_id']){ // Move album if it has a parent 
     $insert_album = $album; 
     unset($albums[$album['id']]); // Remove album from the array, since we are going to insert it into its parent 
     $results = array_search_key($album['parent_album_id'],$albums,$insert_album, $albums); 
     if($results){ 
      $albums = $results; 
     } 
    } 
} 

function array_search_key($needle_key, $array , $insert_album) { 
    foreach($array AS $key=>&$value){ 
     if($key == $needle_key) { 
      $array[$key]['children'][$insert_album['id']] = $insert_album; 
      return $array; 
     } 
     if(is_array($value) && is_array($value['children'])){  
      if(($result = array_search_key($needle_key, $value['children'], $insert_album)) !== false) 
      return $result; 
     } 
    } 
    return false; 
} 

답변

0
// you already managed to get the array into this form 
$albums = array(
    1 => array('id'=>1, 'title'=>'Album 1', 'parentId'=>null), 
    2 => array('id'=>2, 'title'=>'Album 2', 'parentId'=>null), 
    3 => array('id'=>3, 'title'=>'Album 1.1', 'parentId'=>1), 
    4 => array('id'=>4, 'title'=>'Album 1.1.1', 'parentId'=>3), 
    5 => array('id'=>5, 'title'=>'Album 2.1', 'parentId'=>2), 
    6 => array('id'=>6, 'title'=>'Album 1.1.2', 'parentId'=>3), 
    7 => array('id'=>7, 'title'=>'Album 1.1.3', 'parentId'=>3) 
); 

print_r(foo($albums)); 


function foo($albums) { 
    $rv = array(); 
    foreach($albums as &$album) { 
    if (is_null($album['parentId'])) { 
     // no parentId -> entry in the root array 
     $rv[] = &$album; 
    } 
    else { 
     $pid = $album['parentId']; 
     if (!isset($albums[$pid])) { 
     echo 'orphant album: ', $album['id'], "\n"; 
     } 
     else { 
     if (!isset($albums[$pid]['children'])) { 
      $albums[$pid]['children'] = array(); 
     } 
     $albums[$pid]['children'][] = &$album; 
     } 
    } 
    } 
    return $rv; 
} 

인쇄

Array 
(
    [0] => Array 
    (
    [id] => 1 
    [title] => Album 1 
    [parentId] => 
    [children] => Array 
     (
     [0] => Array 
     (
      [id] => 3 
      [title] => Album 1.1 
      [parentId] => 1 
      [children] => Array 
      (
      [0] => Array 
       (
       [id] => 4 
       [title] => Album 1.1.1 
       [parentId] => 3 
      ) 

      [1] => Array 
       (
       [id] => 6 
       [title] => Album 1.1.2 
       [parentId] => 3 
      ) 

      [2] => Array 
       (
       [id] => 7 
       [title] => Album 1.1.3 
       [parentId] => 3 
      ) 

      ) 

     ) 

    ) 

    ) 

    [1] => Array 
    (
    [id] => 2 
    [title] => Album 2 
    [parentId] => 
    [children] => Array 
     (
     [0] => Array 
     (
      [id] => 5 
      [title] => Album 2.1 
      [parentId] => 2 
     ) 

    ) 

    ) 

) 
+0

뭔가 그 기능에 문제가 있습니다. 반환 된 배열에서 ID가 5 인 앨범이 여러 제목으로 여러 번 나타납니다. – makeee

+0

스크립트가 정상적으로 작동합니다. 하지만 여러 요소가 'id'=> 5 (복사 및 붙여 넣기 오류) 인 스크립트 버전의 결과를 붙여 넣었습니다. 수정 됨. – VolkerK

+0

감사합니다. 훌륭한 작품입니다! 내가 만든 변경 사항은 배열을 통해 맨 끝에있는 루프에 있었고 parent_id가있는 모든 최상위 앨범을 제거합니다 (이미 올바른 부모에 삽입 되었기 때문에). – makeee