2010-11-21 27 views
5

PHP kullanıyorum ve bir dizi ile basit bir görevde yardıma ihtiyacım var.Çok boyutlu dizi oluşturma algoritması

Bu benim örnek dizidir:

$arr = array(
    0 => NULL, 
    1 => NULL, 
    2 => NULL, 
    3 => NULL, 
    8 => '2', 
    9 => '2', 
    10 => '2', 
    11 => '2', 
    12 => '3', 
    13 => '3', 
    14 => '8', 
    15 => '8', 
    16 => '14', 
    17 => '14', 
    18 => '14' 
); 

dizinin anahtarları kimlikleri (benzersiz) temsil eder.
Değerler parentIDs, yani üst "düğüm" kimliğidir. NULL, ebeveyn kimliği (yani yeni dizinin 1. boyutu) olmadığı anlamına gelir.

Şimdi, tüm alt öğeleri üst kimliklerinin altında olan yeni ve çok boyutlu bir dizi oluşturmam gerekiyor. (Muhtemelen betimleyici becerilerden yoksun olduğum için çok kafa karıştırıcı geliyor. Aşağıda bir örnek var, daha net bir şey yapmalıyız.)

Örneğimin yeni dizisi, "sıralama" işlevinden sonra nasıl görünecek? Bu çağrı, uygulandı:

 
$arr = array(
0 => array(), 
1 => array(), 
2 => array(
    8 => array(
     14 => array(
      16 => array(), 
      17 => array(), 
      18 => array() 
), 
     15 => array() 
), 
    9 => array(), 
    10 => array(), 
    11 => array() 
), 
3 => array(
    12 => array(), 
    13 => array() 
) 
); 

tüm boş dizi() ler muhtemelen çok temiz ve zarif bir çözüm değil ama ne yazık ki bu ben olmak gerekir yoldur biliyorum!

+1

http://stackoverflow.com/questions/4196157/create-array-tree-from-array-list adresinin kopyası – stillstanding

+1

Aslında sorunumdan biraz farklı, formatım farklı. – user367217

cevap

2

Böylece iç içe fonksiyon doğru ebeveyn verilen referans noktasını katacak ve başlangıç ​​dizideki her bir öğesi için bir kez çağrılmalıdır.

function add_branch(&$tree, $datum, $parent) { 

    // First we have the base cases: 
    // If the parent is NULL then we don't need to look for the parent 
    if ($parent == NULL) { 
     $tree[$datum] = array(); 
     return true; 
    } 

    // If the array we've been given is empty, we return false, no parent found in this branch 
    if (! count($tree)) { 
     return false; 
    } 


    // We loop through each element at this level of the tree... 
    foreach($tree as $key => $val) { 

     // If we find the parent datum... 
     if ($key == $parent) { 

      // We add the new array in and we're done. 
      $tree[$key][$datum] = array(); 
      return true; 
     } 

     // Otherwise, check all the child arrays 
     else { 

      // Now we check to see if the parent can be found in the curent branch 
      // If a recursive call found a parent, we're done 
      if (add_branch($tree[$key], $datum, $parent)) { 
       return true; 
      } 
     } 
    } 

    // If none of the recursive calls found the parent, there's no match in this branch 
    return false; 

} 

Yorumlar, neler olup bittiğini anlayabileceğiniz umuduyla oldukça ayrıntılıdır. Başınızı döndürmek için özyinelemeli fonksiyonlarda biraz okuma yapmanızı tavsiye ederim.

Bu

kullanılabilmesi görecektir: Söz konusu belirtildiği gibi
$arr = array(
0 => NULL, 
1 => NULL, 
2 => NULL, 
3 => NULL, 
8 => '2', 
9 => '2', 
10 => '2', 
11 => '2', 
12 => '3', 
13 => '3', 
14 => '8', 
15 => '8', 
16 => '14', 
17 => '14', 
18 => '14' 
); 


$final = array(); 

foreach ($arr as $datum => $parent) { 
    add_branch($final, $datum, $parent); 
} 

$final

şimdi doğru bitirme dizisi vardır.

0

İki geçişli foreach hile yapar. Bu, tüm çocukları ebeveynlerine tekrarlayan bir şekilde bağlar.

//$array is the input 

//The tree starts out as a flat array of the nodes 
$tree = array_combine(
    array_keys($array), 
    array_fill(0, count($array), array()) 
); 

//link children to parents (by reference) 
foreach($tree as $key => &$row) { 
    if(! is_null($array[$key])) { 
     $tree[ $array[$key] ][ $key ] =& $row; 
    } 
} 

//remove non-root nodes 
foreach(array_keys($tree) as $key) { 
    if(! is_null($array[$key])) { 
     unset($tree[ $key ]); 
    } 
}