Como excluir o objeto da matriz dentro do loop foreach?


140

Eu itero através de uma matriz de objetos e quero excluir um dos objetos com base em sua propriedade 'id', mas meu código não funciona.

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

Alguma sugestão. Obrigado.


Respostas:


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
É seguro remover um elemento de uma matriz dentro de um loop foreach da mesma matriz?
Olivier Pons

25
@ Oliver: normalmente irá gerar um comportamento inesperado, mas você pode fazê-lo com segurança com foreach no php. Leia aqui para um teste: php.net/manual/en/control-structures.foreach.php#88578
pangon

1
@Paritosh Eu sei que você postou isso há muito tempo, mas é porque o PHP usa matrizes associativas. Então você tem um índice que é excluído: e está sendo codificado para JSON como um Objeto. Faz sentido, uma vez que uma matriz associativa é um "dicionário". Pode ajudar alguém que está chegando.
Ryan O'Donnell

1
Você realmente precisa fazer o segundo para cada um? você não pode simplesmente consultar a propriedade 'id' desejada do objeto? Por que verificar todos os outros adereços.
Htafoya 6/12

3
@ htafoya não, você poderia apenas fazer if(isset($element['id']) && $element['id'] == 'searched_value') { unset($array[$elementKey]); }Eu acho que no momento eu apenas copiei e modifiquei seu código para mostrar a ele como fazer unsetcorretamente.
prodigitalson


2

Você também pode usar referências em foreachvalores:

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

9
O elemento $ (usado dentro e fora do foreach) é apenas uma referência para cada elemento na matriz. unset ($ element) quebrará apenas a referência, não destrói o elemento referenciado de sua matriz.
Nicholas

3
@Dev_NIX $element = nullnão iria funcionar, o comprimento $arraypermanece o mesmo, seria apenas conter nulos
Nico Westerdale

1

Isso deve fazer o truque .....

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

1

Tenha cuidado com a resposta principal.

com

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

e chamando a função

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

retorna

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

ao invés de

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

Isso ocorre porque a configuração não reindexa a matriz.

Isso reindexa. (se precisarmos)

$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

Eu não sou muito programador de php, mas posso dizer que em C # você não pode modificar uma matriz enquanto itera. Você pode tentar usar o loop foreach para identificar o índice do elemento ou elementos a serem removidos e excluir os elementos após o loop.


14
Embora seja uma prática ruim na maioria das linguagens, matrizes em PHP são basicamente matrizes associativas que podem ser iteradas em ordem. A exclusão de um elemento anterior não altera as chaves dos elementos que vêm depois dele.
Ignacio Vazquez-Abrams

22
Na verdade, é permitido porque a matriz que foreach usa internamente é uma cópia da matriz original. Dessa forma, modificar a matriz original é perfeitamente seguro.
Juan

68
Na verdade, é permitido porque o php é maluco como o inferno.
Eric G
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.