Comment supprimer un objet du tableau dans la boucle foreach?

140

Je parcours un tableau d'objets et je souhaite supprimer l'un des objets en fonction de sa propriété 'id', mais mon code ne fonctionne pas.

foreach($array as $element) {
    foreach($element as $key => $value) {
        if($key == 'id' && $value == 'searched_value'){
            //delete this particular object from the $array
            unset($element);//this doesn't work
            unset($array,$element);//neither does this
        } 
    }
}

Aucune suggestion. Merci.

ababa
la source

Réponses:

233
foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        if($valueKey == 'id' && $value == 'searched_value'){
            //delete this particular object from the $array
            unset($array[$elementKey]);
        } 
    }
}
prodigitalson
la source
62
Est-il sûr de supprimer un élément d'un tableau dans une boucle foreach du même tableau?
Olivier Pons
25
@Oliver: cela générera généralement un comportement inattendu, mais vous pouvez le faire en toute sécurité avec foreach sur php. Lisez ici pour un test: php.net/manual/en/control-structures.foreach.php#88578
pangon
1
@Paritosh Je sais que vous avez posté ceci il y a longtemps, mais c'est parce que PHP utilise des tableaux associatifs. Vous avez donc un index qui est supprimé: et il est encodé en JSON en tant qu'objet. Cela a du sens, car un tableau associatif est un «dictionnaire». Pourrait aider quelqu'un qui vient.
Ryan O'Donnell le
1
Avez-vous vraiment besoin de faire le deuxième pour chacun? ne pouvez-vous pas simplement interroger la propriété 'id' souhaitée de l'objet? Pourquoi vérifier tous les autres accessoires.
htafoya
3
@htafoya non vous pourriez le faire if(isset($element['id']) && $element['id'] == 'searched_value') { unset($array[$elementKey]); }Je pense qu'à l'époque, je viens de copier et de modifier son code pour lui montrer comment le faire unsetcorrectement.
prodigitals
2

Il semble que votre syntaxe pour unset n'est pas valide et que l'absence de réindexation pourrait causer des problèmes à l'avenir. Voir: la section sur les tableaux PHP .

La syntaxe correcte est indiquée ci-dessus. Gardez également à l'esprit les valeurs de tableau pour la réindexation, afin de ne jamais indexer quelque chose que vous avez précédemment supprimé.

pablo.meier
la source
2

Vous pouvez également utiliser des références sur les foreachvaleurs:

foreach($array as $elementKey => &$element) {
    // $element is the same than &$array[$elementKey]
    if (isset($element['id']) and $element['id'] == 'searched_value') {
        unset($element);
    }
}
air-dex
la source
9
$ element (utilisé dans et hors de foreach) est juste une référence à chaque élément du tableau. unset ($ element) cassera simplement la référence, il ne détruit pas l'élément référencé de son tableau.
Nicholas
3
@Dev_NIX $element = nullne fonctionnerait PAS, la longueur de $arrayreste la même, il contiendrait juste des valeurs nulles
Nico Westerdale
1

Cela devrait faire l'affaire.....

reset($array);
while (list($elementKey, $element) = each($array)) {
    while (list($key, $value2) = each($element)) {
        if($key == 'id' && $value == 'searched_value') {
            unset($array[$elementKey]);
        }
    }
}
Josh
la source
1

Soyez prudent avec la réponse principale.

avec

[['id'=>1,'cat'=>'vip']
,['id'=>2,'cat'=>'vip']
,['id'=>3,'cat'=>'normal']

et appeler la fonction

foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        if($valueKey == 'cat' && $value == 'vip'){
            //delete this particular object from the $array
            unset($array[$elementKey]);
        } 
    }
}

il retourne

[2=>['id'=>3,'cat'=>'normal']

au lieu de

[0=>['id'=>3,'cat'=>'normal']

C'est parce que unset ne réindexe pas le tableau.

Il se réindexe. (si nous en avons besoin)

$result=[];
foreach($array as $elementKey => $element) {
    foreach($element as $valueKey => $value) {
        $found=false;
        if($valueKey === 'cat' && $value === 'vip'){
            $found=true;
            $break;
        } 
        if(!$found) {
           $result[]=$element;
        }
    }
}
magallanes
la source
0

Je ne suis pas vraiment un programmeur php, mais je peux dire qu'en C # vous ne pouvez pas modifier un tableau tout en l'itérant. Vous pouvez essayer d'utiliser votre boucle foreach pour identifier l'index de l'élément ou les éléments à supprimer, puis supprimer les éléments après la boucle.

Corey Sunwold
la source
14
Bien que ce soit une mauvaise pratique dans la plupart des langages, les tableaux en PHP sont essentiellement des tableaux associatifs qui peuvent être itérés dans l'ordre. La suppression d'un élément antérieur ne change pas les clés des éléments qui le suivent.
Ignacio Vazquez-Abrams
22
En fait, c'est autorisé car le tableau utilisé par foreach en interne est une copie du tableau d'origine. De cette façon, la modification du tableau d'origine est parfaitement sûre.
Juan
68
En fait, c'est permis parce que php est foutu comme tout l'enfer.
Eric G