Come eliminare l'oggetto dall'array all'interno del ciclo foreach?


140

Esamino una matrice di oggetti e desidero eliminare uno degli oggetti in base alla proprietà "id", ma il mio codice non funziona.

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

Eventuali suggerimenti. Grazie.


Risposte:


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

62
È sicuro rimuovere un elemento di un array all'interno di un ciclo foreach dello stesso array?
Olivier Pons,

25
@Oliver: di solito genererà un comportamento inaspettato, ma puoi farlo tranquillamente con foreach su php. Dare un Leggi qui per un test: php.net/manual/en/control-structures.foreach.php#88578
pangon

1
@Paritosh So che l'hai pubblicato molto tempo fa, ma è perché PHP utilizza array associativi. Quindi hai un indice che è stato eliminato: e viene codificato in JSON come un oggetto. Ha senso, dal momento che un array associativo è un "dizionario". Potrebbe aiutare qualcuno che sta arrivando.
Ryan O'Donnell,

1
Hai davvero bisogno di fare il secondo per ciascuno? non puoi semplicemente interrogare la proprietà 'id' desiderata dell'oggetto? Perché controllare tutti gli altri oggetti di scena.
htafoya,

3
@htafoya no, potresti semplicemente farlo, if(isset($element['id']) && $element['id'] == 'searched_value') { unset($array[$elementKey]); }penso che al momento ho appena copiato e modificato il suo codice per mostrargli come farlo unsetcorrettamente.
prodigitalson

2

Sembra che la sintassi di unset non sia valida e la mancanza di reindicizzazione potrebbe causare problemi in futuro. Vedi: la sezione sugli array PHP .

La sintassi corretta è mostrata sopra. Tieni inoltre presente i valori di array per la reindicizzazione, in modo da non indicizzare mai qualcosa che hai precedentemente eliminato.


2

Puoi anche usare riferimenti su foreachvalori:

foreach($array as $elementKey => &$element) {
    // $element is the same than &$array[$elementKey]
    if (isset($element['id']) and $element['id'] == 'searched_value') {
        unset($element);
    }
}

9
$ element (usato dentro e fuori dalla foreach) è solo un riferimento a ciascun elemento dell'array. unset ($ element) interromperà semplicemente il riferimento, non distruggerà l'elemento di riferimento dal suo array.
Nicholas

3
@Dev_NIX $element = nullNON funzionerebbe, la lunghezza di $arrayrimane la stessa, conterrebbe solo valori null
Nico Westerdale,

1

Questo dovrebbe fare il trucco .....

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

1

Fai attenzione con la risposta principale.

con

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

e chiamando la funzione

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

ritorna

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

invece di

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

È perché unset non reindicizza l'array.

Reindicizza. (se ne abbiamo bisogno)

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

0

Non sono un programmatore di php, ma posso dire che in C # non è possibile modificare un array mentre si scorre attraverso di esso. Puoi provare a utilizzare il ciclo foreach per identificare l'indice dell'elemento o gli elementi da rimuovere, quindi eliminare gli elementi dopo il ciclo.


14
Mentre è una cattiva pratica nella maggior parte delle lingue, gli array in PHP sono sostanzialmente array associativi che possono essere ripetuti in ordine. L'eliminazione di un elemento precedente non modifica le chiavi degli elementi che lo seguono.
Ignacio Vazquez-Abrams,

22
In realtà, è consentito perché l'array che foreach utilizza internamente è una copia dell'array originale. In questo modo, la modifica dell'array originale è perfettamente sicura.
Juan,

68
In realtà, è permesso perché php è un casino come l'inferno.
Eric G,
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.