Détermination du chemin d'indexage menant à une valeur dans un tableau multi-dimensionnel

Soyez le premier à donner votre avis sur cette source.

Snippet vu 5 659 fois - Téléchargée 16 fois

Contenu du snippet

Cette fonction sert à trouver tous les indices qu'il faut suivre dans un tableau multidimentionnel pour localiser une valeur dans ce tableau.

Elle est surtout pratique si l'on doit travailler sur un tableau dont on ne connait pas la structure et la taille.

Elle renvoie une chaîne contenant tous les indices menant à la valeur recherchée.

La recherche est sensible à la casse, et les index associatifs ne doivent pas contenir d'apostrophes ['].

Source / Exemple :


<?php
function Trouve_indice($Tableau,$Val)
{
static $Drapeau=false;static $Compteur=false;static $Result=array(); static $Tbl_origine=array();
//Cette fonction sert à trouver tous les indices dans un tableau multidimentionnel pour localiser une valeur dans ce tableau

  if($Compteur==false)    //$Compteur permet d'assigner à $Tbl_origine le tableau passé en paramètre lors du premier appel de la fonction
  {                       //En effet, lorsque l'on trouve la valeur le tableau en cours est celui contenant cette valeur.
  $Tbl_origine=$Tableau;
  $Compteur=true;
  }

  if(in_array($Val,$Tableau))
  {
  $Drapeau=true;
  $Result[]=array_search($Val,$Tableau);
    /*On récupère le chemin d'indexation menat à la valeur
    Afin d'éviter Fatal error: Cannot use string offset as an array in..., on :

    - Inverse le tableau de résultats
    - Remonte l'arborescence jusqu'à trouver l'indice "racine" menant à la valeur
    - On renvoie la chaîne de caractères composée */
  
  $Result=array_reverse($Result);

       foreach($Result as $Check)
       {
        //Pour gérer les indices associatifs
         $Guillemets=gettype($Check)=="string" ? "'" : "";
         $Code="[".$Guillemets.$Check.$Guillemets."]".$Code;
  
         eval('$Test=$Tbl_origine'.$Code.';');
         if($Test==$Val) break;
      }
  return $Code;
  }

foreach($Tableau as $Cle=>$Valeur)
{
   if($Drapeau==true) break;//break; Pour remonter l'arborescence d'appel de la fonction en gardant le résultat

   if(is_array($Valeur))
   {
    $Result[]=$Cle; //$Result[]=$Cle: On rajoute l'indice parcouru dans le tableau de résultats
    $Result=Trouve_indice($Valeur,$Val);
   }
}
return $Result;
}
?>

Conclusion :


Un petit exemple :

$Couleurs=array(
array("vert","bleu","jaune","rouge"),
array("rose","violet"),
array("marron","noir","gris",array("lie de vin","caca d'oie","vert d'eau","fuchia","La bonne est la"=>"blanc")),
array("pourpre","orange","kaki"));

$Indice=Trouve_indice($Couleurs,"blanc");
echo $Indice //Ca affiche [2][3]['La bonne est la']

eval('echo $Couleurs'.$Indice.';'); //Cela affichera blanc

A voir également

Ajouter un commentaire

Commentaires

Messages postés
30
Date d'inscription
vendredi 25 novembre 2005
Statut
Membre
Dernière intervention
17 novembre 2009

Bonjour

Ma fonction était bancale car elle ne supprimait pas les tableaux contenant des tableaux qui n'avaient pas la valeur recherchée. Du coup, le résultat retourné contenait, en plus du bon chemin, tous les indices de tableaux ayant au moins un tableau dans leurs éléments.

Ce bug est résolu, et j'ai fait en sorte que la fonction traite les indexs associatifs et numériques.
Messages postés
30
Date d'inscription
vendredi 25 novembre 2005
Statut
Membre
Dernière intervention
17 novembre 2009

Concernant le <? au lieu de <?php, c'est tout simplement parce que, en apprenant le PHP, j'ai vu que l'on pouvait utiliser cette syntaxe. Donc, par soucis de gagner du temps de frappe, j'ai pris cette mauvaise habitude. De plus, je n'ai aucune connaissance en xml.

Je te remercie pour la proposition de code que tu fais, cela démontre la différence entre tes compétences de PHP et les miennes.

Si dans ma soumission j'ai proposé une chaine de caractère, c'est à titre informatif, sachant que pour mes besoins personnels je renverrai un tableau qui me permettra via un eval et une concaténation de chaine de pointer sur l'élément de tableau recherché.

J'ai écris ce code avec comme objectif principal : Rédiger une fonction récursive avec renvoi d'une valeur.

Ne sachant pas ce qu'est une classe ou une fonction divine, j'ai concentré tous mes efforts sur le parcours des tableaux.
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
38
c'est une fonction qui peut se montrer utile, cependant... <?php a la place de <? ne porte plus confusion avec un xml, ce qui te permet de voi ton script fonctionner sur tout serveur :)

Ensuite : pourquoi renvoyer une chaine de caractere ? et pourquoi afficher cette chaine avec print_r ? (dans ton exemple) on ne doit pas avoir de fonction ou classes divine; une classe ou fonction divine fait tout elle meme sans rien demander aux autres... tu devrais renvoyer le tableau directement

j'ai pas teste cette fonction (je ne suis pas sur ma machine...) j'aurais probablement ecrit un truc genre :

function find_recursif($tab, $valeur, $prof=0){
$prof2=$prof+1;
foreach ($tab as $indice=>$a){
if ($a===$valeur){
return array($prof=>$indice);
}else if (gettype($a)==='array' && (false!==($b=find_recursif($a, $valeur, $prof2)))){
$b[$prof]=$indice;
return $b;
}
}
return false;
}

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.