2012-12-14 9 views
15

Uso PHP e mySQL con Idiorm. Potrebbe non essere rilevante.Array gerarchico PHP - Genitori e figli

mio array PHP

  • E 'un rapporto tra genitori e bambino.
  • 0 è il padre principale.
  • Esempio: Radice genitore 0 hanno il bambino 33 che hanno il bambino 27 che hanno il bambino 71.

Questa struttura a matrice può essere modificata, se necessario, per risolvere il problema.

array (
    33 => 
    array (
     0 => '27', 
     1 => '41', 
), 
    27 => 
    array (
     0 => '64', 
     1 => '71', 
), 
    0 => 
    array (
     0 => '28', 
     1 => '29', 
     2 => '33', 
), 
) 

Il mio risultato gerarchica

Qualcosa di simile, ma come un array ...

0 => 
     28 
     29 
     33 
     27 => 
       64 
       71 
     41 

Informazioni

  • La profondità sono sconosciuta ed è può essere illimitata. Ho provato a cercare, ma potrebbe non essere il modo.

miei pensieri

  • Alcuni funzione ricorsiva?
  • Alcuni cicli?

Ho provato entrambi i precedenti, ho appena avuto un casino. È un gioco da ragazzi.

+2

Vedere http://stackoverflow.com/a/8587437/476 per una spinta nella giusta direzione ... – deceze

risposta

36

Il suggerimento di @deceze ha funzionato. Tuttavia, la matrice di ingresso ha bisogno di cambiare un pò, come questo ...

$rows = array(
    array(
     'id' => 33, 
     'parent_id' => 0, 
    ), 
    array(
     'id' => 34, 
     'parent_id' => 0, 
    ), 
    array(
     'id' => 27, 
     'parent_id' => 33, 
    ), 
    array(
     'id' => 17, 
     'parent_id' => 27, 
    ), 
); 

Da https://stackoverflow.com/a/8587437/476:

function buildTree(array $elements, $parentId = 0) { 
    $branch = array(); 

    foreach ($elements as $element) { 
     if ($element['parent_id'] == $parentId) { 
      $children = buildTree($elements, $element['id']); 
      if ($children) { 
       $element['children'] = $children; 
      } 
      $branch[] = $element; 
     } 
    } 

    return $branch; 
} 

$tree = buildTree($rows); 

print_r($tree); 
+0

Ha funzionato benissimo per me. Grazie. –

+0

Ottima risposta! Grazie. – HartleySan

+0

appena aggiunto un piccolo miglioramento nella mia risposta, spero che sia ok! – Danish

4

ho aggiunto le risposte di @Jens Tornell per permettere di definire le opzioni per il nome della colonna di parent_id , il nome della chiave dell'array child e anche il nome della colonna per id.

/** 
* function buildTree 
* @param array $elements 
* @param array $options['parent_id_column_name', 'children_key_name', 'id_column_name'] 
* @param int $parentId 
* @return array 
*/ 
function buildTree(array $elements, $options = [ 
    'parent_id_column_name' => 'parent_id', 
    'children_key_name' => 'children', 
    'id_column_name' => 'id'], $parentId = 0) 
    { 
    $branch = array(); 
    foreach ($elements as $element) { 
     if ($element[$options['parent_id_column_name']] == $parentId) { 
      $children = buildTree($elements, $options, $element[$options['id_column_name']]); 
      if ($children) { 
       $element[$options['children_key_name']] = $children; 
      } 
      $branch[] = $element; 
     } 
    } 
    return $branch; 
} 

Dal momento che la funzionalità è abbastanza universale, sono riuscito a utilizzare la funzione di cui sopra, nella maggior parte dei miei progetti.

1

ottima risposta da @Jens Törnell, volevo solo aggiungere un piccolo miglioramento se il tuo parent_id e id è in realtà una stringa anziché un numero, quindi il metodo fallirà e dopo aver creato l'array figli, creerà di nuovo gli array dei bambini come separati array individuale. Per risolvere il problema, dovresti eseguire il triplo controllo di uguaglianza e indicando il tipo di dati della variabile i.e (stringa) in confronto.

Per string id e parent_id sede a matrice

function buildTree(array $elements, $parentId = 0) { 
    $branch = array(); 

    foreach ($elements as $element) { 
     if ((string)$element['parent_id'] === (string)$parentId) { 
      $children = buildTree($elements, $element['id']); 
      if ($children) { 
       $element['children'] = $children; 
      } 
      $branch[] = $element; 
     } 
    } 

    return $branch; 
} 

inoltre se qualcuno voglia, può aggiungere un terzo parametro di funzionare anche per specificare il tipo di dati delle variabili dinamicamente cioè function buildTree(array $elements, $parentId = 0, $datatype='string') ma poi si avrà per prendere qualsiasi altro errore si verificano.

spero che possa aiutare qualcuno!