2009-12-22 12 views
82

Desidero eseguire il ciclo di un array con foreach per verificare se esiste un valore. Se il valore esiste, voglio cancellare l'elemento che lo contiene.Come si rimuove un elemento dell'array in un ciclo foreach?

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 di una volta si trova il valore. Come lo cancello?

Devo utilizzare foreach per questo problema. Ci sono probabilmente alternative a foreach e sei invitato a condividerle.

risposta

161

Se anche si ottiene la chiave, è possibile eliminare l'elemento in questo modo:

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

Alcuni ulteriori informazioni su come ottimizzare utilizzando 'chiave $ => & $ tag_name' http://stackoverflow.com/a/ 2008893/922522 – Justin

+4

Si noti che gli array indicizzati con elementi non impostati possono essere rappresentati come oggetti invece di matrici dopo un 'json_encode()'. Puoi risolverlo con '$ display_related_tags = array_values ​​($ display_related_tags);' dopo il ciclo 'foreach'. –

+0

Nota: ecco il trucco per aggiungere un valore al ciclo foreach ;-) – MrWashinton

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 vuoi dire 'disinserire'? – amn

0

Come è già stato detto, che ci si vuole fare un foreach con la chiave, e non impostato utilizzando la chiave - ma si noti che la mutazione di un array durante l'iterazione è in generale una cattiva idea, anche se non sono sicuro delle regole di PHP in questo modo.

+2

Un php foreach verrà eseguito sull'intero array indipendentemente. Provare a disabilitare un valore che è prossimo nell'iterazione. Ripeterà sull'offset, ma il valore sarà nullo. –

+0

Se non si modifica la mutazione di un array durante l'iterazione, come si modifica la matrice? Può significare "foreach' o' for' costruzioni invece dell'iterazione in generale? – Gherman

+0

Questo è più di un commento su un'altra risposta che una risposta in sé e per sé. – BFWebAdmin

5

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

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

La stretta operatore comparsion è necessario ==, perché array_search() può restituire 0 come indice di $ unwantedValue.

Inoltre, l'esempio di cui sopra rimuoverà solo il primo valore di $ unwantedValue, se il $ unwantedValue può verificarsi più di una volta nel $ array, è necessario utilizzare array_keys(), per trovare tutti loro:

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

Verificare http://php.net/manual/en/function.array-search.php per ulteriori informazioni.

1

tenta di utilizzare la next(), current() funzioni while, for ciclo.

0

se avete scenario in cui è necessario rimuovere i valori più di uno dalla matrice foreach in questo caso si deve passare il valore con riferimento a ciascuna: 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 che si desidera disinserire le prime voci di loop non vengono ripetute nell'iterazione a scopo di prestazione altrimenti vengono annullate anche dalla memoria perché nella memoria presentano e arriveranno in iterazioni.

2

Se l'array è indicizzato (non associativo), è possibile utilizzare array_splice anziché unset, quindi i numeri di indice vengono riordinati in modo appropriato.

foreach ($arr as $key => $value) { 
    if($value == 'whatever') { 
     array_splice($arr, $key, 1); 
    } 
} 

Se ha, per esempio, questo array indicizzato: $arr = [200,400,600];

  • Uso impostata nel secondo elemento ([1]) comporterebbe la seguente matrice:
array(2) { 
    [0]=> 
    int(200) 
    [2]=> 
    int(600) 
} 
  • Uso array_splice nel secondo elemento ([1]) comporterebbe la seguente matrice:
array(2) { 
    [0]=> 
    int(200) 
    [1]=> 
    int(600) 
} 

Ciò evita potenziale problema con passanti che utilizzano un indice incrementale.

+0

Perché il downvote? C'è qualcosa di sbagliato nella mia risposta? – OMA

15

Una soluzione migliore è quella di utilizzare la funzione array_filter:

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

Come documentazione php legge:

Come foreach basa sul puntatore interno in PHP 5, cambiandolo all'interno del loop può portare a comportamenti imprevisti.

+0

Si noti che il terzo parametro deve essere ARRAY_FILTER_USE_KEY per passare la chiave come $ e qui. – namezero

0

Ci sono già risposte che stanno dando luce su come disinserire. Piuttosto che ripetere codice in tutti i tuoi corsi, fai funzioni come quelle qui sotto e usale nel codice quando richiesto. Nella logica aziendale, a volte non si desidera esporre alcune proprietà. per rimuovere prega di vedere sotto una chiamata di linea

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

chiamata come:

removeKeysFromAssociativeArray($arrValues, $keysToRemove); 
Problemi correlati