Bir foreach döngüsündeki bir dizi öğesini nasıl kaldırırsınız?


127

foreachBir değerin var olup olmadığını kontrol etmek için bir dizide döngü yapmak istiyorum . Değer mevcutsa, onu içeren öğeyi silmek istiyorum.

Takip koduna sahibim:

foreach($display_related_tags as $tag_name) {
    if($tag_name == $found_tag['name']) {
        // Delete element
    }
}

Değer bulunduğunda öğeyi nasıl sileceğimi bilmiyorum. Nasıl silerim?

foreachBu problem için kullanmalıyım . Muhtemelen alternatifleri vardır foreachve bunları paylaşabilirsiniz.

Yanıtlar:


220

Anahtarı da alırsanız, bu öğeyi şu şekilde silebilirsiniz:

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


5
Unset öğelerine sahip dizinlenmiş dizilerin, bir json_encode(). Bunu döngüden $display_related_tags = array_values ($display_related_tags);sonra çözebilirsiniz foreach.
Márton Tamás

Buradaki püf noktasının foreach döngüsüne bir değer katmak olduğunu unutmayın ;-)
Mr Washington

5
Lütfen @Neils cevabına bakın. Özellikle Array of stdClasses ile çalışıyorsanız, beklenmedik hatalarla karşılaşırsınız. Beklenmedik davranışları sever misin? Beni değil.
happy_marmoset

@happy_marmoset Neils cevabı yardımcı olmuyor. Snippet $projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });, sonucu nesneye dönüştürür.
Paritosh

36

Daha iyi bir çözüm, array_filterişlevi kullanmaktır :

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

Php dokümantasyonunun okuduğu gibi:

Foreach, PHP 5'te dahili dizi göstericisine dayandığından, döngü içinde değiştirmek beklenmeyen davranışlara neden olabilir.

PHP 7'de foreach dahili dizi göstericisini kullanmaz.


Burada anahtarı $ e olarak geçirmek için 3. parametrenin ARRAY_FILTER_USE_KEY olması gerektiğini unutmayın.
namezero

@namezero Tamam bu neden burada önemli?
AbraCadaver

@AbraCadaver Belgelerden ( php.net/manual/en/function.array-filter.php ): ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value Default is 0 which will pass value as the only argument to callback instead. Bununla birlikte, bu durumda cevabı tekrar okumak, iddia ettiğiniz gibi elbette önemli olmayacaktır.
namezero

Önemli Diziyi sıralı dizi olarak tutmakla ilgileniyorsanız, display_related_tags = array_values(display_related_tags);onun arkasından aramanız gerekir.
guyaloni

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

3
'unlink' dosyaların bağlantısını kaldırır, değişkenlerle veya daha spesifik olarak dizilerle ilgisi yoktur. Belki de 'ayarlanmadı' demek istiyorsunuz?
amn

6

Dizi üzerinde foreach () döngüsü yapmak yerine, uygun anahtarı bulmak için array_search () kullanmak daha hızlı olacaktır. Küçük dizilerde, daha iyi okunabilirlik için foreach'i kullanırdım, ancak daha büyük diziler veya sıklıkla yürütülen kod için bu biraz daha optimal olmalıdır:

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

Katı karşılaştırma operatörü! == gereklidir, çünkü array_search () $ istenmeyenValue dizini olarak 0 döndürebilir.

Ayrıca, yukarıdaki örnek yalnızca $ istenmeyenValue ilk değerini kaldıracaktır, eğer $ istenmeyenValue $ dizisinde birden çok kez ortaya çıkabiliyorsa, hepsini bulmak için array_keys () kullanmalısınız:

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

Daha fazla bilgi için http://php.net/manual/en/function.array-search.php adresini kontrol edin .


0

foreach dizisinden birden fazla değeri kaldırmanız gereken bir senaryonuz varsa, bu durumda her biri için referansa göre değer iletmeniz gerekir: Bu senaryoyu açıklamaya çalışıyorum:

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

                        }
               }
}

ikinci döngüde, ilk döngüleri kaldırmak istediğiniz girdiler, performans amacıyla yinelemede tekrar gelmezler veya daha sonra bellekten de ayrılamazlar çünkü bellekte var olurlar ve yinelemelerle gelirler.


0

Nasıl bozulacağına ışık tutan cevaplar zaten var. Tüm sınıflarınızda kodu tekrarlamaktansa aşağıdaki gibi işlev yapın ve gerektiğinde kodda kullanın. İş mantığında, bazen bazı özellikleri açığa çıkarmak istemezsiniz. Kaldırmak için lütfen aşağıya bakın

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

Şöyle arayın:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);

-1

Daha önce belirtildiği gibi, anahtarla bir foreach yapmak ve anahtarı kullanarak ayarı kaldırmak istersiniz - ancak yineleme sırasında bir diziyi değiştirmenin genel olarak kötü bir fikir olduğunu unutmayın, ancak PHP'nin bu konudaki kurallarından emin değilim hazırlıksız.


2
Bir php foreach, ne olursa olsun tüm dizi üzerinde çalışacaktır. Yinelemede bir sonraki değeri silmeyi test edin. Göreli konum üzerinde yinelenecek, ancak değer boş olacaktır.
Kevin Peno

Yineleme sırasında bir diziyi değiştirmezseniz, bir diziyi nasıl değiştirirsiniz? Genel olarak yineleme yerine ortalama foreachveya foryapılar olabilir mi?
Gherman

Bu, kendi başına bir cevaptan çok başka bir cevaba dair bir yorumdur.
Uğursuz Sakal
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.