Foreach döngüsünün içindeki diziden nesne nasıl silinir?


140

Bir nesne dizisi üzerinden yineleme ve 'id' özelliğine göre nesnelerden birini silmek istiyorum, ancak benim kod çalışmıyor.

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

Baska öneri. Teşekkürler.


Yanıtlar:


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
Aynı dizinin foreach döngüsü içindeki bir dizinin bir öğesini kaldırmak güvenli midir?
Olivier Pons

25
@Oliver: genellikle beklenmedik davranışlar yaratır, ancak php üzerinde foreach ile güvenle yapabilirsiniz. Bir test için burada bir okuma yapın: php.net/manual/en/control-structures.foreach.php#88578
pangon

1
@Paritosh Bunu uzun zaman önce yayınladığınızı biliyorum, ancak PHP ilişkilendirilebilir diziler kullanıyor. Silinen bir dizininiz var: ve JSON'a Nesne olarak kodlanıyor. İlişkilendirilebilir bir dizi "sözlük" olduğundan mantıklıdır. Gelen birine yardım edebilir.
Ryan O'Donnell

1
Her biri için ikincisini gerçekten yapmanız gerekiyor mu? sadece nesnenin istenen 'id' özelliğini sorgulayamaz mısınız? Neden diğer tüm sahne kontrol edin.
htafoya

3
@htafoya hayır yapabilirdin sadece if(isset($element['id']) && $element['id'] == 'searched_value') { unset($array[$elementKey]); }ben sadece kopyalamak ve ona nasıl unsetdüzgün göstermek için kodunu değiştirdi zaman düşünüyorum .
prodigitalson

2

Görünüşe göre unset için sözdizim geçersiz ve yeniden endeksleme eksikliği gelecekte sorunlara neden olabilir. Bkz: PHP dizileri bölümü .

Doğru sözdizimi yukarıda gösterilmiştir. Yeniden dizine ekleme için dizi değerlerini de unutmayın , böylece daha önce sildiğiniz hiçbir şeyi dizine eklemezsiniz.


2

foreachDeğerlerle ilgili referansları da kullanabilirsiniz :

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

9
$ öğesi (foreach içinde ve dışında kullanılır) dizideki her öğeye yalnızca bir referanstır. unset ($ element) sadece referansı keser, referans verilen elemanı dizisinden yok etmez.
Nicholas

3
@Dev_NIX $element = nullişe yaramaz, $arraykalıntıların uzunluğu aynıdır, sadece null içerecektir
Nico Westerdale

1

Bu hile yapmalı .....

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

1

Ana cevaba dikkat edin.

ile

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

ve işlevi çağırmak

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

geri döner

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

onun yerine

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

Çünkü unset diziyi yeniden endekslemez.

Yeniden endeksler. (ihtiyacımız olursa)

$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

Ben bir php programcı değilim, ama C # içinde yineleme sırasında bir dizi değiştiremezsiniz diyebilirim. Öğenin dizinini veya kaldırılacak öğeleri tanımlamak için foreach döngüsünü kullanmayı, ardından döngüden sonra öğeleri silmeyi deneyebilirsiniz.


14
Çoğu dilde kötü uygulama olsa da, PHP'deki diziler temelde sıralı olarak yinelenebilen ilişkilendirilebilir dizilerdir. Önceki bir öğeyi silmek, öğeden sonra gelen öğelerin anahtarlarını değiştirmez.
Ignacio Vazquez-Abrams

22
Aslında, foreach'in dahili olarak kullandığı dizi orijinal dizinin bir kopyası olduğu için buna izin verilir. Bu şekilde, orijinal diziyi değiştirmek son derece güvenlidir.
Juan

68
Aslında, php tüm cehennem gibi berbat olduğu için izin verilir.
Eric G
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.