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 :

Unset dans une double boucle


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 48
    Par défaut Unset dans une double boucle
    Bonjour à tous,

    Je suis bloqué sur un algo depuis quelques temps et je n'arrive pas à trouver de solution. Voici ce que j'aimerai faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    foreach($myArrays as $myKey => $myArray){
         foreach($myArrays as $otherKey => $otherArray){
              if ($ohterArray == $myArray) break;
              if (//une certaine condition sur les deux tableaux)
                  unset($myArrays[$otherKey]);
         }
    }
    En gros, $myArrays est bien modifié dans la deuxième boucle mais malheureusement ce n'est pas effectif quand on revient dans la première boucle. J'aimerai bien que lorsque l'on revienne dans la première boucle, il n'y ait plus les éléments virés dans la deuxième boucle. Je veux faire ça car j'ai beaucoup de données dans $myArrays et c'est déjà assez lourd de boucler deux fois dessus !

    Alors si quelqu'un aurait une solution à mon problème, je suis preneur

  2. #2
    Membre expérimenté
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    152
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2003
    Messages : 152
    Par défaut
    Un algo d'élimination de doublons ?
    Pas possible, autant que je sache, avec foreach d'avoir le tableau impacté en temps réel.

    Par contre ça marche avec un for

    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
     
    //Tableau a dédoublonner
    $arr = array('A','B','A','C','D','B','E','F','F','A','C','F','D');
     
    $maxval = sizeof($arr);	//nbre d'item dans le tableau
     
    //boucle 1
    for($i=0;$i<$maxval;$i++) {
    	//boucle 2
    	for($j=0;$j<$maxval;$j++) {
    		if ($i == $j)  continue; //on ignore la comparaison avec soi même
    		if($arr[$i] == $arr[$j]) unset($arr[$j]); //si valeur identique on fait sauter la 2eme
    	}
    	$arr = array_values($arr); 	//reindexation du tableau sinon aille aille aille le for
    	$maxval = sizeof($arr);		//recalcul du nombre d'items
    }
    Si tu var_dump le tableau à chaque itération, tu verra qu'il diminue bien de taille en temps réel.

  3. #3
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    Pour éviter de redimensionner le tableau à chaque itération (ce qui peut être problématique), il faut procéder autrement :
    1. A chaque itération : remplir un tableau des clés à supprimer
    2. Faire un array_diff_key() en fin de traitement

    Je pense qu'il serait judicieux que tu postes ton code complet avec tes tests, histoire de voir s'il n'y aurait pas un raccourci. Parce qu'il n'est jamais bon de faire des foreach imbriqués sur le même tableau.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 48
    Par défaut
    Merci pour vos réponses.

    Et je vais essayer d'être plus précis dans ce que je veux faire. Ce n'est pas un algo d'élimination de doublons mais un algo de regroupement de données.
    J'ai un tableau avec des données localisées. Je voudrais regrouper ces données suivant la distance qui les sépare. Donc pour le moment je ne vois pas d'autres solutions que de comparer les données une à une dans une double boucle...

    Voici mon algo complet :
    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
     
    $clusters = array (); //Tableau de tableaux de donnée
    foreach ($datas as $data) {
    	$cluster = array ();
            $cluster ['data'] = array ();
            array_push ( $cluster ['data'], $data );
    	$cluster ['lat'] = $data ['lat'];
    	$cluster ['long'] = $data ['long'];
    	array_push ( $clusters, $cluster );
    }
     
    foreach ($clusters as $keycluster => $cluster) {
    	foreach ($clusters as $keyotherCluster => $otherCluster) {
                   if ($keycluster != $keyotherCluster && distance < à un certain nombre) {
                    array_push ($clusters[$keycluster]['data'], $clusters[$keyotherCluster]['data'][0]);
                    unset($clusters[$keyohterCluster]);
                   }
            }
    }
    Voilà concrètement ce que je voudrais faire. Sauf qu'apparemment la modification de $clusters faite dans la deuxième boucle n'est pas prise en compte dans la première. Et j'ai bien conscience que c'est un algo assez lourd, donc si quelqu'un voit un moyen de l'optimiser, je suis preneur !

  5. #5
    Membre expérimenté
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    152
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2003
    Messages : 152
    Par défaut
    Un problème me viens à l'exprit.

    Prenons un tableau de 4 points a,b,c,d

    avec les distances suivantes:

    ab = 10
    ac = 30
    ad = 10
    bc = 15
    bd = 5

    et imaginons que tu regroupe les points séparés de moins de 12

    Si je suis ton algo avec a en première boucle tu va successivement retirer b et d du tableau puisque ab = 10 et ad = 10

    Mais alors tu n'évaluera jamais bc, bd et cd alors qu'il parait judicieux d'évaluer bd qui a une distance de seulement 5, du coup si tu cherche le plus cours, c'est dommage.

    Par contre une fois a passé en première boucle, il a été évalué avec toutes les autres données, il serait donc judicieux pour alléger le traitement de n'évaluer en 2eme boucle qu'avec les indices supérieurs à celui de la boucle 1

    boucle1 sur indice1 = 0 a sizeof
    boucle2 sur indice2 = indice1+1 à sizeof
    //boucle d'or dans la maison des ours
    fin boucle2
    fin boucle1

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    48
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 48
    Par défaut
    Ah oui, bien vu pour l'opti ! Merci

    Sinon, j'ai réussi à avoir quelque chose qui fonctionne, même si c'est pas très beau.

    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
     
    $finalClusters = array();
    $deleteClusters = array();
     
    foreach ($clusters as $keycluster => $cluster) {
    	for ($keyotherCluster = $keycluster + 1; $keyotherCluster < count($clusters); $keyotherCluster++) {
    		$otherCluster = $clusters[$keyotherCluster];
                   if ($keycluster != $keyotherCluster && distance < à un certain nombre) {
                    array_push ($clusters[$keycluster]['data'], $clusters[$keyotherCluster]['data'][0]);
                    if (!in_array($otherCluster['id'], $deleteClusters)){
    			array_push($deleteCluster, $otherCluster['id']);
    			if (!in_array($cluster['id'], $finalClusters))
    				array_push($finalClusters, $cluster['id']);
    		}   
                 }
            }
    }
    return $this->removeDuplicate($clusters, $finalClusters);
     
    public function removeDuplicate($arrays, $final){
    	$result = array();
    	foreach ($arrays as $array){
    		if (in_array($array['id'], $final))
    			array_push($result, $array);
    	}
    	return $result;
    }
    Ca m'embête un peu de devoir parcourir une fois de plus mon gros tableau pour enfin avoir le bon tableau...

Discussions similaires

  1. Réponses: 1
    Dernier message: 05/06/2015, 20h13
  2. [XL-2010] Utilisation de la Fonction DIR dans une double boucle
    Par Bruno92320 dans le forum Macros et VBA Excel
    Réponses: 16
    Dernier message: 16/12/2014, 20h31
  3. Sommer dans une double boucle for
    Par ju_cayenne dans le forum MATLAB
    Réponses: 1
    Dernier message: 09/09/2014, 16h23
  4. Réponses: 2
    Dernier message: 25/03/2014, 10h20
  5. [XL-2010] Gérer les suppressions d'éléments dans une collection et une double boucle
    Par Rayanea dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 22/10/2013, 10h08

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