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 :

Array - Ciblage recursif


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Webmaster - Développeur/intégrateur web
    Inscrit en
    Septembre 2011
    Messages
    210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Webmaster - Développeur/intégrateur web
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2011
    Messages : 210
    Par défaut Array - Ciblage recursif
    Bonjour à toutes et tous,

    Voilà je souhaiterais savoir si il existe un moyen de cibler l'élement d'un tableau en profondeur (pour obtenir ou modifier sa valeur) sans avoir à indiquer l'arboresence.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <?php
    $repas = array('matin' => array('lundi_matin' => 'Céréales', 'mardi_matin' => 'Pain', 'mercredi_matin' => 'Oeufs'),
                         'midi' =>  array('lundi_midi' => 'Riz', 'mardi_midi' => 'Pattes', 'mercredi_midi' => 'Legumes'),
                         'soir' => array('lundi_soir' => 'Riz', 'mardi_soir' => 'Pattes', 'mercredi_soir' => 'Legumes'));
    Je voudrais récupérer ou modifier la valeur du "lundi_midi" sans avoir à faire : $repas['midi']['lundi_midi'];
    Bien sûr pour mon exemple je pourrais m'en passer mais pour mon script, il s'agit de récupérer ou modifier une valeur dans un tableau sans connaitre l’arborescence potentiellement complexe.
    EDIT : par contre, je précise que les clés seront uniques.

    Quelqu'un connaitrait il une astuce ou un script existant pour répondre à mon besoin ?
    Je pose la question avant de me lancer dans un développement fastidieux :-)

    Merci d'avance pour vos réponse et bonne journée !

  2. #2
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 506
    Par défaut
    Je ne comprend pas bien ?

    ceci :

  3. #3
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Dans l'idéal, je donnerai tout simplement une autre forme au tableau en "l'aplatissant", mais disons qu'il faut garder le tableau avec sa structure originale.

    Une solution consisterait à créer une fonction qui parcourrait le tableau jusqu'à trouver la bonne clef, mais c'est quand même un peu lourdingue. Une autre possibilité serait de créer un tableau associatif dont les valeurs seraient des références aux valeurs du tableau d'origine:
    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
    $ref_repas = [ 'lundi_matin' => &$repas['matin']['lundi_matin'],
                   'mardi_matin' => &$repas['matin']['mardi_matin'],
                   'mercredi_matin' => &$repas['matin']['mercredi_matin'],
                   'lundi_midi' => &$repas['midi']['lundi_midi'],
                   'mardi_midi' => &$repas['midi']['mardi_midi'],
                   'mercredi_midi' => &$repas['midi']['mercredi_midi'],
                   'lundi_soir' => &$repas['soir']['lundi_soir'],
                   'mardi_soir' => &$repas['soir']['mardi_soir'],
                   'mercredi_soir' => &$repas['soir']['mercredi_soir']
                 ];
     
    echo $ref_repas['lundi_soir'], PHP_EOL;
    $ref_repas['lundi_soir'] = 'choucroute';
    echo $repas['soir']['lundi_soir'], PHP_EOL;
    $repas['soir']['lundi_soir'] = 'cassoulet';
    echo $ref_repas['lundi_soir'], PHP_EOL;
    D'ailleurs au lieu d'écrire ce tableau de références à la main, tu peux très bien créer une fonction qui le construise pour toi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function multi2Flat(&$source, &$destination, $ref = false) {
        foreach ($source as $k => &$v) {
            if (is_array($v))
                multi2Flat($v, $destination, $ref);
            else
                $destination[$k] = $ref ? &$v : $v;
        }
    }
     
    $ref_repas = [];
     
    multi2Flat($repas, $ref_repas, true);
    (avec le paramètre $ref par défaut à false, la fonction créera un copie qui ne sera pas liée au tableau d'origine.)

  4. #4
    Membre éprouvé
    Homme Profil pro
    Webmaster - Développeur/intégrateur web
    Inscrit en
    Septembre 2011
    Messages
    210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Webmaster - Développeur/intégrateur web
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2011
    Messages : 210
    Par défaut
    Désolé pour me retour tardif et merci à vous pour le temps passé sur ce post.

    Donc à priori pour ma question "je souhaiterais savoir si il existe un moyen de cibler l’élément d'un tableau en profondeur (pour obtenir ou modifier sa valeur) sans avoir à indiquer l'arboresence", la réponse est NON.

    Dans mon cas j'ai finalement opté pour un traitement du tableau en 2 fois avec 2 foreach, je n'ai pas trouvé d'autre solution à mon casse tête.

    Encore merci, bonne journée et bonnes fêtes !

  5. #5
    Expert confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 420
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 420
    Par défaut
    Il y a la lib SPL avec ses noms barbares mais qui est efficace notamment pour la récursivité quand on ne connait pas la structure du tableau.

    Pour la lecture ça va tout seul puisqu'il suffit de lire une clé du tableau.

    Pour la modification et si l'on reprend le même principe c'est un peu plus complexe puisqu'on doit (plus exactement je ne sais pas faire autrement) créer une référence au tableau pour pouvoir la modifier mais ça ne fait que deux lignes de plus.
    Par 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
    22
    23
    24
    $repas = array('matin' => array('lundi_matin' => 'Céréales', 'mardi_matin' => 'Pain', 'mercredi_matin' => 'Oeufs'),
                         'midi' =>  array('lundi_midi' => 'Riz', 'mardi_midi' => 'Pattes', 'mercredi_midi' => 'Legumes'),
                         'soir' => array('lundi_soir' => 'Riz', 'mardi_soir' => 'Pattes', 'mercredi_soir' => 'Legumes'));
     
    function lireRepas($array,$recherche)
    {
        $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
        foreach($iterator as $key => $value) {if($key == $recherche) return $key . ": " . $value;}	
    }
     
    function modifRepas($array,$recherche,$value)
    {
        $object = json_decode(json_encode($array));
        $iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($object));
        foreach($iterator as $key => $val) {if($key == $recherche) $iterator->offsetSet($key,$value);} 
        return json_decode(json_encode($object), true);
    }
     
    echo lireRepas($repas,'lundi_midi');
    var_dump($repas);
     
    $repas = modifRepas($repas,'lundi_midi','Pâtes');
    echo lireRepas($repas,'lundi_midi');
    var_dump($repas);

  6. #6
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Citation Envoyé par Soundboy39 Voir le message
    Donc à priori pour ma question "je souhaiterais savoir si il existe un moyen de cibler l’élément d'un tableau en profondeur (pour obtenir ou modifier sa valeur) sans avoir à indiquer l'arboresence", la réponse est NON.
    C'est à se demander si tu as lu ma réponse!

Discussions similaires

  1. [XSL][ARRAY]
    Par miloud dans le forum XMLRAD
    Réponses: 4
    Dernier message: 02/10/2003, 15h46
  2. Erreur "size array"
    Par boobob dans le forum C
    Réponses: 3
    Dernier message: 06/08/2003, 10h18
  3. TStringList en array of string
    Par JediKerian dans le forum Langage
    Réponses: 2
    Dernier message: 20/03/2003, 15h37
  4. Réponses: 2
    Dernier message: 23/02/2003, 00h49
  5. passage en paramètre d'un array dynamique 2D
    Par Guigui_ dans le forum Langage
    Réponses: 4
    Dernier message: 27/11/2002, 19h47

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