Come si rimuove un elemento dell'array in un ciclo foreach?


127

Voglio scorrere un array con foreachper verificare se esiste un valore. Se il valore esiste, desidero eliminare l'elemento che lo contiene.

Ho il codice seguente:

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

Non so come eliminare l'elemento una volta trovato il valore. Come lo elimino?

Devo usare foreachper questo problema. Probabilmente ci sono alternative a foreach, e sei il benvenuto a condividerle.

Risposte:


220

Se ottieni anche la chiave, puoi eliminare quell'elemento in questo modo:

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

3
Alcune informazioni aggiuntive sull'ottimizzazione utilizzando $key => &$tag_name stackoverflow.com/a/2008893/922522
Justin

5
Notare che gli array indicizzati con elementi non impostati possono essere rappresentati come oggetti invece che come array dopo un file json_encode(). Puoi risolverlo con $display_related_tags = array_values ($display_related_tags);dopo il foreachciclo.
Márton Tamás

Nota che il trucco qui è aggiungere un valore al ciclo foreach ;-)
Mr Washington

5
Si prega di vedere la risposta di @Neils. Incontrerai bug inaspettati, specialmente se lavori con Array of stdClasses. Ti piacciono i comportamenti inaspettati? Io no.
happy_marmoset

@happy_marmoset La risposta di Neils non aiuta. Snippet $projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });converte il risultato in oggetto.
Paritosh

36

Una soluzione migliore è utilizzare la array_filterfunzione:

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

Come si legge nella documentazione di php :

Poiché foreach si basa sul puntatore interno all'array in PHP 5, modificarlo all'interno del ciclo può portare a un comportamento imprevisto.

In PHP 7, foreach non utilizza il puntatore interno all'array.


Nota che il terzo parametro dovrebbe essere ARRAY_FILTER_USE_KEY per poter passare la chiave come $ e qui.
namezero

@namezero OK perché è importante qui?
AbraCadaver,

@AbraCadaver Dalla documentazione ( 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. Detto questo, leggere di nuovo la risposta in questo caso ovviamente non avrebbe importanza come affermi.
namezero

Importante Se si è interessati a mantenere l'array come array ordinato, è necessario richiamarlo display_related_tags = array_values(display_related_tags);.
guyaloni

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

3
'unlink' scollega i file, non ha nulla a che fare con le variabili o, più specificamente, con gli array. Forse intendi "sconvolto"?
amn

6

Invece di eseguire il ciclo foreach () sull'array, sarebbe più veloce usare array_search () per trovare la chiave corretta. Su piccoli array, vorrei andare con foreach per una migliore leggibilità, ma per array più grandi o codice spesso eseguito, questo dovrebbe essere un po 'più ottimale:

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

È necessario l'operatore di confronto rigoroso! ==, perché array_search () può restituire 0 come indice di $ indesideratoValore.

Inoltre, l'esempio precedente rimuoverà solo il primo valore $ indesideratoValore, se $ indesideratoValore può verificarsi più di una volta nell'array $, dovresti usare array_keys (), per trovarli tutti:

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

Controlla http://php.net/manual/en/function.array-search.php per maggiori informazioni.


0

se hai uno scenario in cui devi rimuovere più di un valore dall'array foreach, in questo caso devi passare il valore per riferimento in ciascuno: cerco di spiegare questo scenario:

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]);

                        }
               }
}

nel secondo ciclo si desidera annullare l'impostazione delle voci dei primi cicli non vengono nuovamente visualizzate nell'iterazione a scopo di esecuzione oppure disattivate anche dalla memoria perché in memoria si presentano e arriveranno in iterazioni.


0

Ci sono già risposte che stanno dando luce su come disarmarsi. Piuttosto che ripetere il codice in tutte le tue classi, fai funzionare come di seguito e usalo nel codice quando richiesto. Nella logica aziendale, a volte non si desidera esporre alcune proprietà. Si prega di vedere sotto una chiamata di linea da rimuovere

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;
}

Chiama come:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);

-1

Come è già stato accennato, vorresti fare un foreach con la chiave e non impostare usando la chiave, ma nota che la modifica di un array durante l'iterazione è in generale una cattiva idea, anche se non sono sicuro delle regole di PHP su questo estemporaneo.


2
Un php foreach verrà eseguito sull'intero array indipendentemente. Prova a disinserire un valore che è successivo nell'iterazione. Itererà sull'offset, ma il valore sarà nullo.
Kevin Peno

Se non si modifica un array durante l'iterazione, come si fa a mutare un array? Può essere meschino foreacho forcostruzioni invece di iterazione in generale?
Gherman

Questo è più un commento su un'altra risposta che una risposta in sé e per sé.
Barba
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.