IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Fonction récursive pour créer un array


Sujet :

Langage PHP

  1. #1
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut Fonction récursive pour créer un array
    Bonjour à tous,

    j'ai un problème qui me taraude depuis quelques temps.

    j'ai un tableau qui renvoie ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Array (
    [0] => Europe
    [1] => West
    [2] => Germany
    [3] => France
    [4] => Switzerland
    [5] => East
    [6] => Czech Republic
    [7] => Slovakia
    [8] => Poland
    // etc ...
    )
    je cherche à créer un tableau compatible json, c'est à dire de la forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    $array=
    array(
      array("pays"=>"Europe",
        "enfants"=>array(
          array("pays"=>"West",
            "enfants"=>
              array(
                array("pays"=>"Germany"),
                array("pays"=>"France"),
                array("pays"=>"Switzerland")
    	  )
          ),
          array("pays"=>"East",
            "enfants"=>
              array(
                array("pays"=>"Czech Republic"),
                array("pays"=>"Slovakia"),
                array("pays"=>"Poland")
              )
          )
        )
      )
    );
    pour trouver les enfants, j'ai une fonction qui flagge les pays, (en gros si le pays est une région, alors il a des enfants). Pour ce faire j'ai essayé d'utiliser une fonction récursive:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    function ListArray($tb)
    {
     
    	$connect=palo_init('localhost','7777','admin','admin');
     
    	$rettab=array();
     
            // foreach element of the list
            foreach($tb as $tb_elt)
            {
                    //element is consolidated : call the recursive function to list the children
                    if(palo_etype($connect,'Demo','Regions',$tb_elt)=='consolidated')
                    {		
                    	array_push($rettab,array("title"=>$tb_elt));
                            array_push($rettab,array("children"=>ListArray($tb_elt)));
                    }
                    else //basis element
                    {
     
    			array_push($rettab,array("title"=>$tb_elt));
                    }
            }
     
            return $rettab;
    }
    il me semble que c'est la bonne méthode, mais ca ne me donne pas ce que je souhaite... je m'emmêle entre array_push, array_merge etc.

    une idée ? je ne sais pas trop si mon problème est clair ou pas

    merci par avance pour votre aide (toujours précieuse)

  2. #2
    Membre chevronné

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 205
    Billets dans le blog
    1
    Par défaut
    Si le tableau que tu fournis en entrée à ta fonction est celui que tu nous présentes en premier, ta fonction récursive n'ira pas bien loin puisque les éléments de ton tableau ($tb_elt chez toi) sont des chaines de caractère !

    array_push($rettab,array("children"=>ListArray($tb_elt))); ne te donnera donc pas ce que tu veux

    Si j'ai bien compris, ta fonction palo_etype t'indique s'il s'agit d'un père ou d'un enfant, mais comment fais-tu le distinguo entre 'Europe' et 'West' ?
    Par exemple, quel statut a 'West' qui est à la fois le fils de 'Europe' et le père de 'France') ?
    Sauf à ce qu'Europe soit un élément particulier qui toujours à la racine et seul à son niveau, il te manque une information.
    si ce post vous a été utile, si votre problème est résolu.
    Pensez-y !
    __________________________________
    Doc officielle PHP | FAQ PHP | Cours PHP

  3. #3
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Salut k'amm et merci pour ta réponse super rapide !

    Citation Envoyé par k'amm Voir le message
    Si le tableau que tu fournis en entrée à ta fonction est celui que tu nous présentes en premier, ta fonction récursive n'ira pas bien loin puisque les éléments de ton tableau ($tb_elt chez toi) sont des chaines de caractère !
    je ne comprends pas trop en quoi le fait que ce soit des chaines de caractère joue ? alors effectivement si j'ai bien compris array_merge par exemple ne fonctionnerait pas car il écraserait les chaines en question...

    Citation Envoyé par k'amm Voir le message
    Si j'ai bien compris, ta fonction palo_etype t'indique s'il s'agit d'un père ou d'un enfant,
    tu as effectivement tout compris

    Citation Envoyé par k'amm Voir le message
    mais comment fais-tu le distinguo entre 'Europe' et 'West' ?
    tu as effectivement soulevé une excellente critique, que je n'avais pas pris en compte. C'est effectivement bien beau de savoir s'il est consolidé ou pas, mais si on a pas sa place dans la hiérarchie on ne va effectivement pas aller bien loin...

    je vais voir comment je peux résoudre le problème

    merci encore

  4. #4
    Membre chevronné

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 205
    Billets dans le blog
    1
    Par défaut
    je ne comprends pas trop en quoi le fait que ce soit des chaines de caractère joue ? alors effectivement si j'ai bien compris array_merge par exemple ne fonctionnerait pas car il écraserait les chaines en question...
    Tu as un tableau de chaînes de caractères.
    Donc à chaque itération, $tb_elt sera une chaîne de caractère.

    Cependant, tu appelles ta fonction ListArray avec en argument $tb_elt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    array_push($rettab,array("children"=>ListArray($tb_elt)));
    ListArray va donc prendre ta chaîne de caractère et boucler sur chaque lettre de celle-ci. Hors - sauf erreur de ma part - ce que tu souhaites faire à cette ligne est que ListArray boucle sur le reste des éléments de ton tableau !


    N'hésites pas à mettre des traces (echo, logs) pour mieux voir ce qui se passe à chaque tour de boucle
    si ce post vous a été utile, si votre problème est résolu.
    Pensez-y !
    __________________________________
    Doc officielle PHP | FAQ PHP | Cours PHP

  5. #5
    Membre Expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Par défaut
    Ton tableau source n'a qu'une dimension, je ne vois alors pas le besoin d'une fonction récursive.

    Pour toi "Europe", c'est également une région ?

  6. #6
    Membre Expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Par défaut
    Je peux voir un truc comme ça, mais cela implique de repérer les "continents".
    Cela dit, je ne vois pas comment tu ferais autrement si tu veux repérer un break sur un autre continent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    <?php
    $data = array (
        'Europe',
        'West',
        'Germany',
        'France',
        'Switzerland',
        'East',
        'Czech Republic',
        'Slovakia',
        'Poland',
        'Asie',
        'West',
        "pays de l'ouest",
        'East',
        "pays de l'est de l'asie",
    );
     
    $regions = array(
        'West',
        'East',
    );
     
    $continents = array('Europe', 'Asie');
     
    $result = array();
     
    $buffer = array();
     
    $continent = '';
    $region = '';
     
    foreach ($data as $value){
        if (in_array($value, $continents)) {
            $continent = $value;
        }
        elseif (in_array($value, $regions)) {
            $region = $value;
        }
        else {
            $result[$continent][$region][] = $value;
        }
    }
     
    var_dump($result);

  7. #7
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    Je peux savoir pourquoi tu n'écris pas directement un fichier JSON statique plutôt que d'essayer de le générer ?

    Tu sais, les pays et continents ça change pas tous les mercredis...

  8. #8
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut correction du code
    Bonsoir à tous et merci infiniment pour vos réponses.

    Citation Envoyé par Benjamin Delespierre
    Je peux savoir pourquoi tu n'écris pas directement un fichier JSON statique plutôt que d'essayer de le générer ?
    Bonne remarque, en fait j'utilise l'API PHP d'une solution de business intelligence (voir ma signature ) ; donc en fait la liste de pays n'est qu'un exemple, à terme je souhaiterais pouvoir utiliser ce script avec des données plus hétérogènes et dynamique

    Citation Envoyé par s.n.a.f.u
    Cela dit, je ne vois pas comment tu ferais autrement si tu veux repérer un break sur un autre continent.
    effectivement, j'y ai réfléchi, et il y a une fonction dans l'API qui permet de récupérer le niveau de l'élément (1 pour Europe, 2 pour West et East, 3 pour leurs enfants)

    Citation Envoyé par s.n.a.f.u
    Ton tableau source n'a qu'une dimension, je ne vois alors pas le besoin d'une fonction récursive.
    autre bonne remarque, en fait je pensais à une fonction récursive car chaque élément peut être enfant d'un autre, mais parent de n autres. Et je suis aussi arrivé à la conclusion qu'au final le tableau ne peut-être que multi-dimensionnel.

    En fait si on reprend les pays sus-cités, je devrais être capable de remplir le tableau ainsi (j'utilise dans cet exemple "entité" pour éviter de parler régions ou de pays car au final ce sont tous des éléments)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $rettab=array();
     
    $rettab[0][0]["entite"]="Europe";
    $rettab[0][0]["enfants"][0]["entite"]="West";
    $rettab[0][0]["enfants"][0]["enfants"][0]["entite"]="France";
    $rettab[0][0]["enfants"][0]["enfants"][1]["entite"]="Germany";
    $rettab[0][0]["enfants"][0]["enfants"][2]["entite"]="Switzerland";
    $rettab[0][0]["enfants"][1]["entite"]="East";
    $rettab[0][0]["enfants"][1]["enfants"][0]["entite"]="Czech Republic";
    $rettab[0][0]["enfants"][1]["enfants"][1]["entite"]="Slovakia";
    $rettab[0][0]["enfants"][1]["enfants"][2]["entite"]="Poland";
    // pareil si un pays est direct rattaché à Europe (et sans enfants):
    $rettab[0][0]["enfants"][2]["entite"]="San Marino";
    lorsque j'affiche le tout ca me donne ce que je veux. l'idée c'est maintenant de variabiliser tout ca, càd de créer la fonction qui prend comme paramètre l'élément le plus haut, et qui liste tout en cascade...

    est-ce que le modus operandi vous parait faire du sens ?

    Merci encore pour votre aide !

  9. #9
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Re-bonsoir,

    je viens de sortir ca du plus profond de mon cerveau (enfin ce qu'il m'en reste):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function ListArray($top_elt)
    {
    	$montableau=array();	
    	$montableau[0]['entite']=$top_elt;
            // foreach element of the list
            foreach($children as $child) 
            {
                    //element is consolidated : call the recursive function to list the children
                    if(palo_etype($connect,'Demo','Regions',$child)=='consolidated')
                    {
    			$montableau[0]['children'][]['pays']=$child;
    			ListArray($child);
    		}
                    else //basis element
                    {
    			$montableau[0]['children'][]['pays']=$child;
                    }
            }        
            return $montableau;
    }
    ca me retourne partiellement ce que je veux (il s'arrête au niveau 2, à savoir Europe, West, East et San Marino)

    ce qu'il me manque ce serait une syntaxe du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $montableau=$montableau . ["children"][]["entite"]=$child
    (c'est à dire "concaténer" les nouveaux éléments au tableau précédent)

    une idée ? désolé pour les posts multiples

  10. #10
    Membre chevronné

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 205
    Billets dans le blog
    1
    Par défaut
    Tu lui passes quoi en entrée, à ta fonction, du coup ?
    Et tu as résolu comment le problème du distinguo père/fils pour tes entités qui ont les deux propriétés à la fois (West par exemple) ?
    si ce post vous a été utile, si votre problème est résolu.
    Pensez-y !
    __________________________________
    Doc officielle PHP | FAQ PHP | Cours PHP

  11. #11
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Citation Envoyé par k'amm
    Tu lui passes quoi en entrée, à ta fonction, du coup ?
    Et tu as résolu comment le problème du distinguo père/fils pour tes entités qui ont les deux propriétés à la fois (West par exemple) ?
    en fait je lui passe l'élément top, et je liste les enfants à chaque fois si c'est un élément consolidé (en appelant la fonction de facon récursive). est-ce qu'il vaut mieux passer tout le tableau ? je n'en suis pas sûr, c'est un peu confus

    pour le distingo père/fils, en fait je ne sais pas vraiment si c'est bien nécessaire du coup si on a la récursivité...

    non ?

  12. #12
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Hello,

    je me fais des noeuds au cerveau depuis une semaine là dessus sans succès

    c'est vraiment compliqué ou c'est moi qui ai un problème ?

  13. #13
    Expert confirmé
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Par défaut
    A toute fin utile, j'ai une classe qui peut t'aider:
    - https://github.com/bdelespierre/coba...Collection.php

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?php
    require_once "Collection.php";
     
    $collection = new Cobalt_Util_Collection;
    $collection->set('path.to.treasure', 'here');
     
    // équivalent à
     
    $collection = new Cobalt_Util_Collection(array(
        'path' => array(
            'to' => array(
                'trasure' => 'here',
            )
        )
    ));
     
    // conversion JSON
     
    $json = $collection->toJson();
     
    echo $json->path->to->tresure; // here

  14. #14
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Bonjour à tous,

    je me permets de revenir sur le sujet après quelques temps d'absence (et de galère) ; j'ai encore un peu de mal à comprendre :-/

    en fait grâce à vos réponses j'ai compris que j'avais nécessairement besoin d'un relation de type parent/enfant (l'ordre ne suffisant pas)

    du coup j'ai pu générer le tableau suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    Array
    (
        [0] => Array
            (
                [name] => Europe
                [children] => Array
                    (
                        [0] => West
                    )
            )
        [1] => Array
            (
                [name] => West
                [children] => Array
                    (
                        [0] => Germany
                        [1] => France
                    )
            )
        [2] => Array
            (
                [name] => Germany
                [children] => 
            )
        [3] => Array
            (
                [name] => France
                [children] => 
            )
    )
    qui une fois encore n'est qu'un extrait.

    j'ai essayé d'utiliser la récursion mais ca ne fonctionne pas du tout...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function buildTree($inputarray)
    {
    	$arrayout=array();
    	foreach ($inputarray as &$arrayelt)
    	{
    	  if (is_array($arrayelt['children']))
    	  {
    		$arrayout['name']=$arrayelt['name'];
    		$arrayout['children']=buildTree($arrayout['name']);
    	  }
    	  else
    	  {
    		$arrayout['name']=$arrayelt['name'];
    	  }
    	}	
    	return $arrayout;
    }
    auriez-vous une piste pour moi ? en fait je me demande si c'est le concept qui est foireux, ou moi qui ne sait pas bien utiliser les arrays...

    d'avance merci !

  15. #15
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2008
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2008
    Messages : 64
    Par défaut
    Salut,

    Si j'ai bien compris, tu arrives à sortir un tableau présent dans ton premier bout de code et tu veux le transformer en tableau multi dimensionnel avec relations "parent / enfant" avec ton second bout de code ?

    Si oui, il y a quelques incohérences, dont la plus importante : dans ta récursivité, tu appelles ta fonction "buildTree" sur une chaine de caractère (le nom de l'enfant) et non pas sur la liste des enfants. A aucun moment tu te sers de ce nom d'enfant dans le reste du code, donc tu ne risques pas de sortir ce que tu veux.

    Voilà ce que tu veux vraiment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    /**
      * Renvoie un tableau au format $array('name' => $nom, 'children' => array(array('name' => $nom, 'children' => ...), array('name' => $nom2, 'children' => ...)) 
      * @param $inputArray tableau initial contenant tes données
      * @param $nameToCheck nom de ta région pour récupérer les données
      */
    function buildTree($inputArray, $nameToCheck){
        $arrayFinal = array();
        // On boucle sur la donnée initiale
        foreach($inputArray as $data){
            // Si on a le bon nom, on vérifie qu'il y ait ou non une liste d'enfants
            if($data['name'] == $nameToCheck){
                // Quoi qu'il en soit, on récupère le nom car il sera retourné
                $arrayFinal['name'] = $data['name'];
                // S'il y a des enfants, on renvoie un tableau d'enfants de format array(array('name' => x, 'children' => array()), array('name' => y, 'children' => ...))
                if(is_array($data['children'])){
                    // Pour chaque enfant, tu récupère les infos le concernant. Ne pas oublier de passer le tableau initial, car il contient toutes les données dont tu as besoin
                    foreach($data['children'] as $childrenName){
                        $arrayFinal['children'][] = buildTree($inputArray, $childrenName);
                    }
                }else{
                    // Si tu veux garder l'élément "children" présent dans ton tableau final, tu rajoutes ça
                    $arrayFinal['children'] = null;
                }
            }
        }
        return $arrayFinal;
    }
     
    // Données initiales que tu récupères
    $inputData = array(
        array('name' => 'Europe', 'children' => array('West','East')),
        array('name' => 'West', 'children' => array('Germany','France')),
        array('name' => 'Germany', 'children' => null),
        array('name' => 'France', 'children' => null),
        array('name' => 'East', 'children' => array('Boukoukastan','Roquefort-La-Bedoule')),
        array('name' => 'Boukoukastan', 'children' => array('Ville1', 'Ville2')),
        array('name' => 'Roquefort-La-Bedoule', 'children' => array('Ville3', 'Ville4')),
        array('name' => 'Ville1', 'children' => null),
        array('name' => 'Ville2', 'children' => null),
        array('name' => 'Ville3', 'children' => null),
        array('name' => 'Ville4', 'children' => null),
    );
    // Affiche la donnée initiale
    echo '<pre>';
    print_r($inputData);
    echo '</pre>';
     
    // Construit le tableau "relationnel"
    $dataFinal = buildTree($inputData, 'Europe');
     
    // Affiche le résultat
    echo '<pre>';
    print_r($dataFinal);
    echo '</pre>';
    Comme tu le vois, avec ce code tu n'es pas limité à 3 niveaux, mais à une infinité, si tant est que ta donnée est juste dans ton tableau initial.

    L'inconvénient de ce code est que, plus il y a d'informations dans le tableau initial, plus ça va être lourd, car pour chaque élément tu boucles sur l'intégralité du tableau initial.

    Une question comme ça, as-tu la possibilité de sortir la donnée différemment ? Voire d'utiliser un ORM comme Doctrine qui intègre directement ce genre de fonctionnement (à condition que ta BDD soit relationnelle) ? Dans ta base de données, comment sont stockées / liées ces données ?

  16. #16
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Bonjour Meyfarth,

    merci pour ton code qui fonctionne à la perfection et que, en bonus (ou alors c'est l'essentiel ;-), j'ai parfaitement compris vu qu'il était parfaitement clair et commenté :-))

    Une question comme ça, as-tu la possibilité de sortir la donnée différemment ?
    je pense que oui (l'API que j'utilise est relativement flexible) ; quel serait le format le plus optimal à sortir selon toi ?

    j'ai vu sur le Net des solutions qui utilisent le parent de chaque élément (exemple : array("name"=>"West", "parent"=>
    "Europe") mais il me semble que la philosophie de la base de données que j'utilise me l'interdit. : un élément peut en effet avoir plusieurs parents (dans plusieurs hiérarchies différentes). Donc le parent d'un élément n'est pas uniquement déterminé par son nom, mais aussi la hiérarchie dans laquelle il se trouve. Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Europe
      West
      East
     
    Europe2
      West
    Voire d'utiliser un ORM comme Doctrine qui intègre directement ce genre de fonctionnement (à condition que ta BDD soit relationnelle) ? Dans ta base de données, comment sont stockées / liées ces données ?
    il s'agit en fait d'une base de données multidimensionnelle qui s'appelle Palo (voir ma signature :-))

    Merci beaucoup pour votre aide !

  17. #17
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2008
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2008
    Messages : 64
    Par défaut
    Bonjour,

    En toute honnêteté, je ne connais absolument pas PALO et le site web ne dispose pas d'assez d'infos pour que je puisse me représenter rapidement quel type de données il peut sortir.

    Je te parlais de Doctrine car il permet d'avoir une représentation "objet" d'une base de données. Tu gères non plus des entrées dans une base, mais des objets représentant ces entrées. Du coup, en une requête, il est capable de te sortir toutes les infos que tu veux, au format où tu les veux (relation parent / enfant en l’occurrence). L'inconvénient est qu'il peut être assez lourd (il sort beaucoup d'informations, dont la plupart te sont inutiles à toi mais nécessaires à son fonctionnement) et il nécessite une base de données relationnelle. Je ne pense pas qu'il soit compatible avec PALO.

    Quoi qu'il en soit, as-tu une idée de quel type de données tu peux sortir ? Tableau associatif (comme tu l'as montré) ? Jointures ? Autres ?

    Sans ça, je ne vois pour l'instant aucune autre solution que celle que j'ai pu te proposer ...

    Bonne journée,

  18. #18
    Membre éclairé Avatar de laloune
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2005
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Mai 2005
    Messages : 487
    Par défaut
    Bonjour Meyfarth,

    effectivement Doctrine semble fait uniquement pour les bases relationnelles, ce dont je ne dispose pas.

    je pense que pour l'instant le tableau associatif est le seul moyen de sortir les données (en tous cas en utilisant l'API php)

    Je vais essayer de me débrouiller avec ca dans l'immédiat.

    Merci infiniment pour ton aide en tout cas.

  19. #19
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2008
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2008
    Messages : 64
    Par défaut
    Avec plaisir !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonction récursive pour remplissage Array
    Par WibiMaster dans le forum Langage
    Réponses: 15
    Dernier message: 14/02/2011, 08h41
  2. [MySQL] Fonction récursive pour affichage arborescence
    Par Mister Paul dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 01/12/2007, 19h30
  3. Réponses: 6
    Dernier message: 12/04/2007, 20h30
  4. Réponses: 10
    Dernier message: 03/07/2006, 11h32
  5. Fonctions récursives pour parcourir un arbre
    Par mikedavem dans le forum C
    Réponses: 4
    Dernier message: 05/06/2006, 12h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo