web-dev-qa-db-fra.com

PHP tableau hiérarchique - Parents et enfants

J'utilise PHP et MySQL avec Idiorm . Cela pourrait ne pas être pertinent.

Mon PHP tableau

  • C'est une relation entre parents et enfants.
  • 0 est le parent racine.
  • Exemple: Le parent racine 0 a l’enfant 33 qui a l’enfant 27 qui a L’enfant 71.

_ {Cette structure de tableau peut être modifiée si nécessaire pour résoudre le problème.

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

Mon résultat hiérarchique

Quelque chose comme ça, mais comme un tableau ...

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

Information

  • La profondeur est inconnue et peut être illimitée. J'ai essayé, mais ce n'est peut-être pas le cas.

Mes propres pensées

  • Une fonction récursive?
  • Un peu de boucles?

J'ai essayé les deux de ce qui précède, juste un désordre. C'est une évidence.

17
Jens Törnell

La suggestion de @deceze a fonctionné. Cependant, le tableau d’entrée doit changer un peu, comme ceci ...

$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,
    ),
);

De 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 );
41
Jens Törnell

J'ai ajouté aux réponses de @Jens Törnell afin de permettre la définition des options pour le nom de colonne de parent_id, le nom de clé du tableau d'enfants et également le nom de colonne pour l'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;
}

Comme la fonctionnalité est assez universelle , j'ai réussi à utiliser la fonction ci-dessus dans la plupart de mes projets.

5
Fariz Luqman

excellente réponse de @Jens Törnell, je voulais juste ajouter une petite amélioration: si votre id_ parent et id est en fait une chaîne au lieu d'un nombre, la méthode ci-dessus échouera et après avoir créé un tableau d'enfants, elle créera à nouveau ces tableaux d'enfants en tant que tableaux individuels séparés. Afin de résoudre ce problème, vous devez effectuer une vérification triple égal et en indiquant le type de données de la variable i.e (chaîne) en comparaison.

Pour les identifiants basés sur des chaînes et Parent_id dans un tableau

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;
}

en outre, si quelqu'un le souhaite, il peut ajouter un troisième paramètre afin de spécifier également le type de données des variables de manière dynamique, par exemple, mais function buildTree(array $elements, $parentId = 0, $datatype='string'), mais vous devrez alors éliminer toute autre erreur.

j'espère que ça va aider quelqu'un!

3
Danish
public function createTree (&$list, $parentId = null) {
    $tree = array();
    foreach ($list as $key => $eachNode) {
        if ($eachNode['parentId'] == $parentId) {
            $eachNode['children'] = $this->createTree ($list,$eachNode['id']);
            $tree[] = $eachNode;
            unset($list[$key]);
        }
    }
    return $tree;
}

Dans cette fonction, passez le tableau associatif et si le plus grand parent n'est pas null, transmettez simplement l'id le plus parent comme second argument.

0
Asad Iftikhar