2011-09-26 2 views
0

일반적인 중첩 트리 모델을 가지고 있는데 레벨이나 깊이를 기반으로 '자식'배열로 배열을 만들고 싶지만 저에게는 효과가없는 것 같습니다. . 여기에 내가 지금 가지고있는 것 :PHP 배열에서 중첩 된 트리 모델을 통과하지 못하도록

while($this->tax->getTreeNext($nodes)) 
{ 

    $level = $this->tax->getTreeLevel($nodes); 

    if($level != 0){ 
     echo $level . '-' . $current_level; 
     if($level > $current_level){ 
      $terms[$i] = array(
        'term_id' => $terms[$i-1]['term_id'], 
        'name' => $terms[$i-1]['name'], 
        'level' => $terms[$i-1]['level'], 
         'children' => array(
         'term_id' => $nodes['row']['term_id'], 
         'name'  => $nodes['row']['name'], 
         'level'  => $level,    
         ) 
       ); 

      unset($terms[$i-1]); 
     }else{ 

      $terms[$i] = array(
       'term_id' => $nodes['row']['term_id'], 
       'name'  => $nodes['row']['name'], 
       'level'  => $level 
      ); 
     } 

     $current_level = $level; 
     $i++; 
    } 
} 

이것은 하나의 자식에게는 효과가 있지만 아이들에게는 자식이 없을 때 ...이 문제를 해결하는 방법은 무엇입니까?

감사합니다.

편집 :

이 작업에 가까운 것으로 나타납니다 최신입니다 : 나무는 각 노드에 관련된 깊이 값이에 전달

function process(&$arr, &$prev_sub = null, $cur_depth = 1) { 

    $cur_sub = array(); 
    while($line = current($arr)){ 
     if($line['depth'] < $cur_depth){ 
      return $cur_sub; 
     }elseif($line['depth'] > $cur_depth){ 


      $prev_sub = $this->process($arr, $cur_sub, $cur_depth + 1); 

     }else{ 

      $cur_sub[$line['term_id']] = array('term_id' => $line['term_id'], 'name' => $line['name']); 
      $prev_sub =& $cur_sub[$line['term_id']]; 
      next($arr); 
     } 
    } 
    return $cur_sub; 
} 

. 현재 문제는 elseif($line['depth'] > $cur_depth)입니다. 노드에 자식이있는 경우 자식에 대한 배열 만 반환하지만 해당 노드 이름이나 term_id는 포함되지 않습니다.

감사합니다.

+3

반복 대신 반복. – usoban

+0

잘 모르겠습니다 ... 예를 게시 할 수 있습니까? – dzm

+0

데이터 구조에 대해 좀 더 자세히 설명해 주시겠습니까? 당신의 나무는 어떻게 정의되고 저장됩니까? –

답변

1

현재 데이터 구조가 어떻게 보이는지 알 수 없으므로 트리를 가로 지르는 간단한 예를 살펴보십시오.

$treeRoot = $this->tax->getRoot(); 

$result = traverse($treeRoot, 0); 

function traverse($root, $level){ 
$arr = array(); 

$arr['term_id'] = $root['row']['term_id']; 
$arr['name'] = $root['row']['name']; 
$arr['level'] = $level; 

while($child = $root->getNextChild()){ 
    $arr['children'][] = traverse($child, $level+1); 
} 

return $arr; 
} 

그래서 트리 루트에서 시작하여 첫 번째 수준의 배열을 채 웁니다. 그런 다음 당신은 뿌리의 자식들과 함께 계속하지만, 당신은 한 단계 더 깊숙이갑니다. 당신은 뿌리와 똑같은 일을합니다. 당신은 데이터를 채우고 아이들의 아이들에게갑니다. 트리의 맨 아래에 도달하면, 마지막 (grandgrandgrand) 자식은 자식이 남아 있지 않다는 것을 알기 때문에 부모에게 자신을 반환합니다 (일반적인 배열). 그 부모는 그 자신을 부모에게 되 돌리는 등, 다시 루트에 도달 할 때까지 계속됩니다.

그리고 voilà, 중첩 배열이 있습니다. 일반적으로 이런 종류의 구조는 트리로 남겨 두지 만, 정확히 무엇이 결과를 원하는지 알지 못하기 때문에 (위의 예는 제공하지 않음) 위의 코드를 자신의 구현을위한 참조로 사용하십시오.

+0

고마워요.이게 정확히 보이는 것 같아요. 무한 루프가 생깁니다. 확실하지 않습니다. – dzm

+0

흠, 이상합니다. while()은 리프가 자식을 가지지 않기 때문에 가장 낮은 레벨에서 멈추어야하므로 루프도 실행해서는 안됩니다. 디버깅을 시도하고 사이클이 진행되는 곳을 찾아 질문을 업데이트하십시오. – usoban

+0

고맙습니다. 최근 질문으로 업데이트했습니다. – dzm

관련 문제