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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 : 51
    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 : 51
    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
    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 !

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

+ 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