Comment supprimer un élément de tableau dans une boucle foreach?


127

Je veux parcourir un tableau avec foreachpour vérifier si une valeur existe. Si la valeur existe, je souhaite supprimer l'élément qui la contient.

J'ai le code suivant:

foreach($display_related_tags as $tag_name) {
    if($tag_name == $found_tag['name']) {
        // Delete element
    }
}

Je ne sais pas comment supprimer l'élément une fois la valeur trouvée. Comment le supprimer?

Je dois utiliser foreachpour ce problème. Il existe probablement des alternatives foreachet vous pouvez les partager.

Réponses:


220

Si vous obtenez également la clé, vous pouvez supprimer cet élément comme ceci:

foreach ($display_related_tags as $key => $tag_name) {
    if($tag_name == $found_tag['name']) {
        unset($display_related_tags[$key]);
    }
}

3
Quelques informations supplémentaires sur l'optimisation à l'aide de $key => &$tag_name stackoverflow.com/a/2008893/922522
Justin

5
Notez que les tableaux indexés avec des éléments non définis peuvent être représentés comme des objets au lieu de tableaux après un json_encode(). Vous pouvez résoudre ce problème avec $display_related_tags = array_values ($display_related_tags);après la foreachboucle.
Márton Tamás

Notez que l'astuce ici est d'ajouter une valeur à la boucle foreach ;-)
Mr Washington

5
Veuillez consulter la réponse @Neils. Vous rencontrerez des bogues inattendus, surtout si vous travaillez avec Array of stdClasses. Aimez-vous les comportements inattendus? Pas moi.
happy_marmoset le

@happy_marmoset La réponse de Neils n'aide pas. Extrait $projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });il convertit le résultat en objet.
Paritosh

36

Une meilleure solution consiste à utiliser la array_filterfonction:

$display_related_tags =
    array_filter($display_related_tags, function($e) use($found_tag){
        return $e != $found_tag['name'];
    });

Comme le lit la documentation php :

Comme foreach repose sur le pointeur de tableau interne de PHP 5, le modifier dans la boucle peut conduire à un comportement inattendu.

En PHP 7, foreach n'utilise pas le pointeur de tableau interne.


Notez que le 3ème paramètre doit être ARRAY_FILTER_USE_KEY afin de passer la clé en tant que $ e ici.
namezero

@namezero OK, pourquoi est-ce important ici?
AbraCadaver

@AbraCadaver De la documentation ( php.net/manual/en/function.array-filter.php ): ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value Default is 0 which will pass value as the only argument to callback instead. Cela dit, relire la réponse dans ce cas, bien sûr, peu importe ce que vous prétendez.
namezero

Important Si vous souhaitez conserver le tableau en tant que tableau ordonné, vous devez l'appeler display_related_tags = array_values(display_related_tags);après.
guyaloni

9
foreach($display_related_tags as $key => $tag_name)
{
    if($tag_name == $found_tag['name'])
        unset($display_related_tags[$key];
}

3
'unlink' dissocie les fichiers, cela n'a rien à voir avec des variables ou, plus spécifiquement, des tableaux. Peut-être voulez-vous dire «non défini»?
amn le

6

Au lieu de faire la boucle foreach () sur le tableau, il serait plus rapide d'utiliser array_search () pour trouver la clé appropriée. Sur les petits tableaux, j'irais avec foreach pour une meilleure lisibilité, mais pour des tableaux plus grands ou du code souvent exécuté, cela devrait être un peu plus optimal:

$result=array_search($unwantedValue,$array,true);
if($result !== false) {
  unset($array[$result]);   
}

L'opérateur de comparaison strict! == est nécessaire, car array_search () peut renvoyer 0 comme index de $ unwantedValue.

De plus, l'exemple ci-dessus supprimera uniquement la première valeur $ unwantedValue, si $ unwantedValue peut apparaître plus d'une fois dans le $ array, vous devez utiliser array_keys (), pour les trouver toutes:

$result=array_keys($array,$unwantedValue,true)
foreach($result as $key) {
  unset($array[$key]);
}

Consultez http://php.net/manual/en/function.array-search.php pour plus d'informations.


0

si vous avez un scénario dans lequel vous devez supprimer plus d'une valeur du tableau foreach, dans ce cas, vous devez passer la valeur par référence pour chacune: j'essaie d'expliquer ce scénario:

foreach ($manSkuQty as $man_sku => &$man_qty) {

               foreach ($manufacturerSkus as $key1 => $val1) {

  // some processing here and unset first loops entries                     
 //  here dont include again for next iterations
                           if(some condition)
                            unset($manSkuQty[$key1]);

                        }
               }
}

dans la deuxième boucle, vous voulez désarmer les premières entrées de boucles ne reviennent pas dans l'itération à des fins de performance ou alors désarmées de la mémoire aussi parce qu'en mémoire elles se présentent et viendront dans des itérations.


0

Il y a déjà des réponses qui donnent la lumière sur la façon de désarmer. Plutôt que de répéter le code dans toutes vos classes, faites fonctionner comme ci-dessous et utilisez-le dans le code chaque fois que nécessaire. Dans la logique métier, vous ne souhaitez pas toujours exposer certaines propriétés. Veuillez voir ci-dessous un appel de ligne pour supprimer

public static function removeKeysFromAssociativeArray($associativeArray, $keysToUnset)
{
    if (empty($associativeArray) || empty($keysToUnset))
        return array();

    foreach ($associativeArray as $key => $arr) {
        if (!is_array($arr)) {
            continue;
        }

        foreach ($keysToUnset as $keyToUnset) {
            if (array_key_exists($keyToUnset, $arr)) {
                unset($arr[$keyToUnset]);
            }
        }
        $associativeArray[$key] = $arr;
    }
    return $associativeArray;
}

Appelez comme:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);

-1

Comme cela a déjà été mentionné, vous voudriez faire un foreach avec la clé et désarmer à l'aide de la clé - mais notez que la mutation d'un tableau pendant l'itération est en général une mauvaise idée, bien que je ne sois pas sûr des règles de PHP à ce sujet désinvolte.


2
Un php foreach s'exécutera sur l'ensemble du tableau malgré tout. Testez la désactivation d'une valeur qui est la suivante dans l'itération. Il itérera sur le décalage, mais la valeur sera nulle.
Kevin Peno

Si vous ne mutez pas un tableau pendant l'itération, comment faire muter un tableau du tout? Peut-être une moyenne foreachou des forconstructions au lieu de l'itération en général?
Gherman

C'est plus un commentaire sur une autre réponse qu'une réponse en soi.
Sinister Beard
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.