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 :

Recherche dans un tableau associatif à deux dimensions


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Points : 38
    Points
    38
    Par défaut Recherche dans un tableau associatif à deux dimensions
    Ami(e)s développeurs(euses) bonjour,

    Je suis confronté à une difficulté pour faire de la recherche dans un tableau associatif à deux dimensions. En effet j'ai un tableau d'objets et je voudrais extraire tous les objets dont la clé "A" est égale à '8' (c'est un exemple bien entendu).

    J'ai essayé d'utiliser une fonction récupérée sur php.net ( http://fr.php.net/array_search ) mais elle ne convient pas aux tableaux associatifs. J'ai donc bidouillé une petite fonction mais je pense qu'elle peut être optimisée; telle quelle elle doit consommer beaucoup de ressources si mon tableau est conséquent.

    Pour être plus clair voici un exemple:

    Code php : 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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    <?php
    	$meule = array(
    					array( "id" => '1001', "A" => '8', "B" => '3'),
    					array( "id" => '1002', "A" => '8', "B" => '9', "C" => '5', "D" => '1'),
    					array( "id" => '1003', "A" => '1', "B" => '7'),
    					array( "id" => '1004', "A" => '8', "B" => '5', "C" => '7'),
    					array( "id" => '1005', "A" => '8'),
    					array( "id" => '1006', "A" => '3', "B" => '7')
    					);
    
    	function recursive_array_search($champ, $valeur, $tableau) 
    	{
    		$rs = array();
    		foreach($tableau as $obj) 
    		{
    			foreach($obj as $key => $val)
    			{
    				if(($key == $champ) && ($val == $valeur))
    				{
    					$rs[] = $obj;
    				}
    			}
    		}
    		return $rs;
    	}
    
    	var_dump(recursive_array_search("A", '8', $meule));
    ?>
    
    /* 
    	RÉSULTATS pour un triage suivant les critères 'A == 8' :
    	array(4) {
    		[0]=>
    			array(3) {
    				["id"]=>
    				string(4) "1001"
    				["A"]=>
    				string(1) "8"
    				["B"]=>
    				string(1) "3"
    			}
    		[1]=>
    			array(5) {
    				["id"]=>
    				string(4) "1002"
    				["A"]=>
    				string(1) "8"
    				["B"]=>
    				string(1) "9"
    				["C"]=>
    				string(1) "5"
    				["D"]=>
    				string(1) "1"
    			}
    		[2]=>
    			array(4) {
    				["id"]=>
    				string(4) "1004"
    				["A"]=>
    				string(1) "8"
    				["B"]=>
    				string(1) "5"
    				["C"]=>
    				string(1) "7"
    			}
    		[3]=>
    			array(2) {
    				["id"]=>
    				string(4) "1005"
    				["A"]=>
    				string(1) "8"
    			}
    	}
    */


    Qu'en pensez vous, puis-je rendre ma fonction plus rapide et moins gourmande?

    Merci

  2. #2
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    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 888
    Points : 6 632
    Points
    6 632
    Par défaut
    Bonjour,

    oui, il faut supprimer le second foreach qui ne sert à rien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function recursive_array_search($champ, $valeur, $tableau) {
        $rs = array();
        foreach($tableau as $obj) {
            if(isset($obj[$champ]) && $obj[$champ] === $valeur)
                $rs[] = $obj;
        }
        return $rs;
    }
    Tu peux aussi utiliser array_filter:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function recursive_array_search($champ, $valeur, $tableau) {
        return array_filter($tableau, function ($item) use($champ, $valeur) {
            return isset($item[$champ]) && $item[$champ] === $valeur;
        });
    }
    Attention tout de même au fait que array_filter préserve les clefs du tableau d'origine. Si cela pose problème, tu peux toujours faire un passage par array_values:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function recursive_array_search($champ, $valeur, $tableau) {
        return array_values(array_filter($tableau, function ($item) use($champ, $valeur) {
            return isset($item[$champ]) && $item[$champ] === $valeur;
        }));
    }
    Note: pour être vraiment rigoureux, tu peux remplacer tous les comparateurs == par === afin de contrôler le type. Si c'est plus contraignant lors de l'appel de la fonction, ça évite des faux positifs.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Points : 38
    Points
    38
    Par défaut
    La dernière proposition me semble parfaite en effet. Je ferai tes tests de performances mais ça m'a l'air d'être Jacques (tout bon quoi).

    Merci

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Points : 38
    Points
    38
    Par défaut
    Après quelques tests je reviens vers vous... pour vous donner mes résultats.

    Voici ma procédure de test:
    Je génère aléatoirement un gros tableau à deux dimensions (5000 tableaux dans un seul) et je le trie à la recherche de 'A == 8'.
    J'ai bien fait le test une vingtaine de fois, avec 5000 tableaux imbriqués j'obtiens en moyenne entre 175 et 210 occurences.

    Code php : 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
    <?php
    	$champs = array("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
    	$numbers = array(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);
     
    	$megatab = array(); //initialisation du tableau général
     
    	for($i=1;$i<=5000;$i++)
    	{
    		shuffle($numbers);
    		shuffle($champs);
    		$megatab[$i] = array_combine($champs,$numbers);
    	} //génération du tableau
     
    	echo "Triage suivant les crit&egrave;res 'A == 8' : <pre>";
    	var_dump(recursive_array_search("A", '8', $megatab)); //triage du tableau général
    	echo "</pre>";	
    ?>

    En termes de performances, pour 180 occurences avec ma fonction je suis à 1/10 de seconde de temps d'exécution, alors qu'avec la dernière fonction de CosmoKnacki je tourne plutôt vers 0,065 seconde.

    Sa fonction est donc plus performante!

    A noter par contre que j'ai du remplacer les '===' par des '==' pour la comparaison, sinon le résultat est toujours NULL.

    Voilà voilà merci encore pour le coup de main.

  5. #5
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 888
    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 888
    Points : 6 632
    Points
    6 632
    Par défaut
    A noter par contre que j'ai du remplacer les '===' par des '==' pour la comparaison, sinon le résultat est toujours NULL.
    Bien évidemment! === compare non seulement la valeur des deux opérandes, mais aussi leur type. Or dans ton exemple, tu utilises un tableau de nombres array(1,2,3,4...) et tu appelles la fonction avec un string '8'. Il est donc normal que le test échoue. Il faut soit utiliser un tableau de string array('1', '2', '3', '4',...) soit appeler la fonction avec un nombre recursive_array_search("A", 8, $megatab).

    Utiliser === est loin d'être une légère nuance par rapport à ==. À titre d'exemple, regarde ce que te renvoie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var_dump(""==0);
    var_dump(""===0);
    donc si j'appelle la fonction recursive_array_search("A", "", $megatab) il me renverra tous les items où A vaut le nombre 0. (et vice versa)

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 06/02/2012, 20h47
  2. Recherche dans un tableau associatif
    Par ericduval dans le forum Langage
    Réponses: 5
    Dernier message: 02/12/2009, 12h03
  3. Tableau associatif à deux dimensions
    Par Blo0d4x3 dans le forum Langage
    Réponses: 1
    Dernier message: 24/01/2009, 00h18
  4. Réponses: 6
    Dernier message: 19/11/2008, 10h53
  5. Un string dans un tableau de deux dimensions...
    Par FinalSpirit dans le forum C++
    Réponses: 5
    Dernier message: 15/01/2006, 14h29

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