Jak usunąć obiekt z tablicy w pętli foreach?


140

Iteruję przez tablicę obiektów i chcę usunąć jeden z obiektów na podstawie jego właściwości „id”, ale mój kod nie działa.

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

Jakieś sugestie. Dzięki.


Odpowiedzi:


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
Czy można bezpiecznie usunąć element tablicy w obrębie pętli foreach tej samej tablicy?
Olivier Pons

25
@Oliver: zwykle generuje nieoczekiwane zachowanie, ale możesz to zrobić bezpiecznie z foreach na php. Przeczytaj tutaj do testu: php.net/manual/en/control-structures.foreach.php#88578
pangon

1
@Paritosh Wiem, że opublikowałeś to dawno temu, ale to dlatego, że PHP używa tablic asocjacyjnych. Więc masz indeks, który został usunięty: i jest kodowany do JSON jako obiekt. Ma to sens, ponieważ tablica asocjacyjna jest „słownikiem”. Może pomóc komuś, kto przyjdzie.
Ryan O'Donnell

1
Czy naprawdę musisz zrobić sekundę dla każdego? czy nie możesz po prostu zapytać o żądaną właściwość „id” obiektu? Po co sprawdzać wszystkie inne rekwizyty.
htafoya,

3
@htafoya no you can po prostu zrobić if(isset($element['id']) && $element['id'] == 'searched_value') { unset($array[$elementKey]); }Myślę, że wtedy właśnie skopiowałem i zmodyfikowałem jego kod, aby pokazać mu, jak to zrobić unsetpoprawnie.
prodigitalson

2

Wygląda na to, że twoja składnia unset jest nieprawidłowa, a brak ponownego zindeksowania może spowodować problemy w przyszłości. Zobacz: sekcja o tablicach PHP .

Prawidłowa składnia jest pokazana powyżej. Pamiętaj również o wartościach tablicowych do ponownego zindeksowania, więc nigdy nie indeksujesz czegoś, co wcześniej usunąłeś.


2

Możesz również użyć odwołań do foreachwartości:

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 (używany w foreach i poza nim) jest po prostu odniesieniem do każdego elementu tablicy. unset ($ element) po prostu przerwie odwołanie, nie zniszczy elementu, do którego się odwołuje, z jego tablicy.
Nicholas

3
@Dev_NIX $element = nullNIE zadziała, długość $arraypozostaje taka sama, po prostu zawiera wartości null
Nico Westerdale

1

To powinno załatwić sprawę .....

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

1

Uważaj na główną odpowiedź.

z

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

i wywołując funkcję

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

wraca

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

zamiast

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

Dzieje się tak, ponieważ brak ustawienia nie powoduje ponownego indeksowania tablicy.

To reindeksuje. (jeśli tego potrzebujemy)

$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

Nie jestem programistą php, ale mogę powiedzieć, że w C # nie można modyfikować tablicy podczas iteracji. Możesz spróbować użyć pętli foreach do zidentyfikowania indeksu elementu lub elementów do usunięcia, a następnie usunąć elementy po pętli.


14
Chociaż w większości języków jest to zła praktyka, tablice w PHP są w zasadzie tablicami asocjacyjnymi, które można iterować w kolejności. Usunięcie wcześniejszego elementu nie zmienia kluczy elementów, które następują po nim.
Ignacio Vazquez-Abrams

22
Właściwie jest to dozwolone, ponieważ tablica, której wszyscy używają wewnętrznie, jest kopią oryginalnej tablicy. W ten sposób modyfikowanie oryginalnej tablicy jest całkowicie bezpieczne.
Juan,

68
Właściwie jest to dozwolone, ponieważ php jest szalony jak diabli.
Eric G
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.