PHP: Bir diziden belirli bir öğe nasıl kaldırılır?


160

Öğelerin adını bildiğimde bir öğeyi diziden nasıl kaldırabilirim? Örneğin:

Bir dizi var:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');

kullanıcı girer strawberry

strawberry kaldırıldı.

Tam olarak açıklamak için:

Virgülle ayrılmış öğelerin listesini depolayan bir veritabanım var. Kod, söz konusu seçeneğin bulunduğu kullanıcı seçimini temel alarak listeden alınır. Yani, eğer çilek seçtikleri her girişte kod çeker çilek bulunur sonra split () kullanarak bir diziye dönüştürür. Onları diziden kullanıcı tarafından seçilen öğeleri, örneğin bu çilek kaldırmak istiyorum.




Yanıtlar:


296

array_searchAnahtarı almak ve unsetbulunursa kaldırmak için kullanın :

if (($key = array_search('strawberry', $array)) !== false) {
    unset($array[$key]);
}

array_searchbir öğe bulunmazsa false ( PHP 4.2.0'a kadar null) döndürür .

Aynı değere sahip birden fazla öğe varsa array_keys, anahtarları tüm öğelere almak için kullanabilirsiniz :

foreach (array_keys($array, 'strawberry') as $key) {
    unset($array[$key]);
}

Garip bir sonuç almak. Her zaman sadece bir örnek olacağından ilk önerinizi kullandım. Test etmek için sadece anahtar değeri çıktı vardı. Çalışmış. Ancak, unset alışkanlık.
dcp3450 15:10

1
while (odbc_fetch_row ($ runqueryGetSubmenus)) {$ submenuList = odbc_result ($ runqueryGetSubmenus, "alt menüler"); $ submenuArray = bölünmüş (',', $ submenuList); if (($ key = dizi_search ($ name, $ submenuArray))! == false) {unset ($ submenuArray [$ key]); }}
dcp3450 15:02

@ dcp3450: Peki ne yapıyorsun $submenuArray? (Her döngünün $submenuArrayüzerine yazılacağını unutmayın.)
Gumbo

daha iyi açıklamak için sorumu güncelledim. Temel olarak kod, bu örnekteki "çilek" öğelerini seçerek bir veritabanındaki girdiler arasında dolaşır. Böylece, kullanıcı bir seçim => kodunu alt menülerin altına girer ve bu seçeneğe sahip herhangi bir liste bulur => bu listeyi bir diziye dönüştürür => seçilen seçeneği kaldırır.
dcp3450 15:10

1
Anladım! Yeni diziyi DB'ye yeniden yazmıyordum. Bu kadar uzun süre koda baktığınızda işleri kaçırmak kolaydır.
dcp3450 15:10

153

array_diff()1 hat çözümü için kullanın :

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi', 'strawberry'); //throw in another 'strawberry' to demonstrate that it removes multiple instances of the string
$array_without_strawberries = array_diff($array, array('strawberry'));
print_r($array_without_strawberries);

... ekstra fonksiyonlara veya foreach döngüsüne gerek yok.


8
Bu çözüm, en iyi çözümlerden daha okunaklıdır.
Robbert

strawberryİlk dizide olmasa da , $array_without_strawberriesbelirli bir öğenin dizide olmadığından emin olmak istiyorsanız dizide tehlikeli kod kullanılabilir hale gelir .
Erfan

5
@Erfan Talebiniz yanlış. $a = array_diff(array(), array('strawberry'));- $ a boş bir dizidir.
bancer

1
Haklısın @bancer - muhtemelen array_intersect veya başka bir şey düşünüyordum.
Erfan

1
array_diff (), işaretli yanıttan daha zariftir.
Dom DaFonte

36
if (in_array('strawberry', $array)) 
{
    unset($array[array_search('strawberry',$array)]);
}

2
Çilek dizide olup olmadığını test etmelisiniz .
Gumbo

Gumbo'nun tavsiyelerine uyarak, öğeyi diziden kaldırmadan önce doğrulamayı içerecek şekilde değiştirildi.
John Conde

2
Ayrıca, belirli bir öğeyi sildikten sonra indekslerin yeniden hizalanmadığını unutmayın. Başka bir deyişle, dizin dizisinde boşluklar olacaktır. Örneğinizden 'çilek'i silerseniz,' kivi 'hala dizin 4'e sahip olacak ve dizin 2 basitçe kaybolacaktır. Örneğin, ($ i = 0; $ i <.., $ i ++) döngülerinde olduğu gibi, kodunuzun dizin dizisinin bütünlüğüne bağlı olup olmadığı önemlidir.
the-banana-king

2
Muz kralının söylediklerine eklemek için, diziyi yeniden endekslemek istiyorsanız, yapmanız yeterlidir $my_array = array_values($my_array);.
ryeguy

2
Bu çözüm doğru olsa da TWICE ( in_arrayve array_search) dizisini arar . array_searchGumbo cevabında olduğu gibi dönüşü kullanmak daha etkilidir
Bogdan D

21

Burada düz bir dizi kullanıyorsanız (durum böyle görünüyorsa), bunun yerine şu kodu kullanmalısınız:

if (($key = array_search('strawberry', $array)) !== false) {
    array_splice($array, $key, 1);
}

unset($array[$key]) yalnızca öğeyi kaldırır, ancak düz diziyi yeniden sıralamaz.

Diyelim ki bir dizimiz var ve array_splice kullanıyoruz:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
array_splice($array, 2, 1);
json_encode($array); 
// yields the array ['apple', 'orange', 'blueberry', 'kiwi']

Unset ile karşılaştırıldığında:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
unset($array[2]);
json_encode($array);
// yields an object {"0": "apple", "1": "orange", "3": "blueberry", "4": "kiwi"}

unset($array[$key])Diziyi nasıl yeniden sıralamadığına dikkat edin .


Resmen unsethiçbir şey iade etmiyor. Yani json_encode(unset($array[2]))bir karşılaştırma için uygun değildir.
robsch

Bu tam olarak ihtiyacım olan şey, ericluwj
ana

12

Öğeleri belirli bir koşula göre kaldırmak için dizi filtresini kullanabilirsiniz $v:

$arr = array_filter($arr, function($v){
    return $v != 'some_value';
});

Downvote. Bu düşük kaliteli (yalnızca kodlu bir yanıt olduğu ve ayrıştırma hatası verdiği için), içinde yalnızca anonim bir işlev kullanan D.Martin yönteminin bir kopyasıdır array_filter(). Ben şahsen benim uygulamada anonim bir işlev kullanacak olsa da, SO ile ilgili doğru eylemin, bu sayfanın şişirilmemesi için bir mikro iyileştirme yapmak istiyorsanız D.Martin'in cevabına yorum yapmak veya düzenlemek olduğuna inanıyorum. Lütfen bu yinelenen yanıtı silin.
mickmackusa

4

Böyle olacak:

 function rmv_val($var)
 {
     return(!($var == 'strawberry'));
 }

 $array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');

 $array_res = array_filter($array, "rmv_val");

4

Bu, dizideki birden çok değeri silebilen basit bir yinelemedir.

    // Your array
    $list = array("apple", "orange", "strawberry", "lemon", "banana");

    // Initilize what to delete
    $delete_val = array("orange", "lemon", "banana");

    // Search for the array key and unset   
    foreach($delete_val as $key){
        $keyToDelete = array_search($key, $list);
        unset($list[$keyToDelete]);
    }

Bu, PHP geliştiricilerinin zaten oluşturdukları için verimsiz, ev haddelenmiş bir alternatiftir array_diff(). Bu nasıl üç oy aldı? Hiç kimse bu cevabı faydalı bulamamalı veya kendi projelerinde kullanmamalıdır. Bu yanıtı silmenizi öneririm - bu, hesabınızı düşük kaliteli bir yanıttan kurtarmaya, bu sayfadaki yanıt bloğunu azaltmaya ve size Disiplinli bir rozet kazanmaya hizmet eder. Bir ödül için silmek için zamanınız olması için downvote'umu erteleyeceğim.
mickmackusa

4

Sadece u tek satır yapabilirsiniz. Diziden öğe kaldırılacak


$array=array_diff($array,['strawberry']);


3

Şu anda bu işlevi kullanıyorum:

function array_delete($del_val, $array) {
    if(is_array($del_val)) {
         foreach ($del_val as $del_key => $del_value) {
            foreach ($array as $key => $value){
                if ($value == $del_value) {
                    unset($array[$key]);
                }
            }
        }
    } else {
        foreach ($array as $key => $value){
            if ($value == $del_val) {
                unset($array[$key]);
            }
        }
    }
    return array_values($array);
}

Kaldırılması gereken öğeleri içeren bir dizi veya yalnızca bir dize girebilirsiniz. Şöyle yazın:

$detils = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
$detils = array_delete(array('orange', 'apple'), $detils);

VEYA

$detils = array_delete('orange', $detils);

Ayrıca yeniden dizine ekler.


2
Bu çok kıvrımlı ve ilmiklidir. Bu nasıl 3 upvotes kazandı?!?
mickmackusa

2

Bu sorunun bir çok cevabı vardır ama ben kullanıldığında çünkü bir şey daha eklemek istiyorum unsetveyaarray_diff belirli bir öğe kaldırıldığında yeni dizinin dizinleriyle oynamak için birkaç sorun yaşadığım (ilk dizin kaydedildiğinden)

Örneğe geri dönüyorum:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
$array_without_strawberries = array_diff($array, array('strawberry'));

veya

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
unset($array[array_search('strawberry', $array)]);

Sonucu yazdırırsanız elde edersiniz:

foreach ($array_without_strawberries as $data) {
   print_r($data);
}

Sonuç:

> apple
> orange
> blueberry
> kiwi

Ancak dizinler kaydedilecek ve böylece öğenize aşağıdaki gibi erişeceksiniz:

$array_without_strawberries[0] > apple
$array_without_strawberries[1] > orange
$array_without_strawberries[3] > blueberry
$array_without_strawberries[4] > kiwi

Ve böylece son dizi yeniden endekslenmez. Bu nedenle unsetveya öğesinden sonra eklemeniz gerekir array_diff:

$array_without_strawberries = array_values($array);

Bundan sonra dizinizin normal bir dizini olacaktır:

$array_without_strawberries[0] > apple
$array_without_strawberries[1] > orange
$array_without_strawberries[2] > blueberry
$array_without_strawberries[3] > kiwi

Bu gönderi ile ilgili: Re-Index Array

resim açıklamasını buraya girin

Umarım yardımcı olur


1

Daha iyi bir yaklaşım, değerlerinizi ilişkilendirilebilir bir dizide anahtarlar olarak tutmak ve daha sonra array_keys()gerçek diziyi istediğinizde çağırmak olabilir . Bu şekilde array_searchelemanınızı bulmak için kullanmanıza gerek kalmaz .


1
Yayınınız bir cevap değil yorum. Lütfen sorunun kendisinde silin ve gönderin.
mickmackusa

1

PHP dizisinin cevabı değere göre silinir (anahtar değil) https://stackoverflow.com/users/924109/rok-kralj tarafından verilmektedir

IMO kaldırdığı ve değişmediği için en iyi cevaptır

array_diff( [312, 401, 15, 401, 3], [401] ) // removing 401 returns [312, 15, 3]

Güzelce genelleştirir, isterseniz aynı anda istediğiniz kadar öğeyi kaldırabilirsiniz.

Feragatname: Benim çözümüm, dizinin yeni bir kopyasını oluştururken, eskisini değiştiren kabul edilen cevabın aksine sağlam tutar. Bu yüzden biraz daha yavaş olabilir.


1

Aynı sorunun cevabını arıyordum ve bu konuyla karşılaştım. Kombinasyonu: İki ana yolları görmek array_searchve unsetve kullanımı array_diff. İlk bakışta, ilk yöntemin daha hızlı olacağı bana geldi, çünkü ek bir dizinin oluşturulmasını gerektirmiyor (kullanırkenarray_diff ). Ama küçük bir kriter yazdım ve ikinci yöntemin sadece daha kısa değil, aynı zamanda daha hızlı olmasını sağladım! Bunu sizinle paylaşmaktan mutluluk duyuyorum. :)

https://glot.io/snippets/f6ow6biaol


0

Diziler gibi anahtarları aramak için array_key_exists kullanmayı tercih ederim :

Array([0]=>'A',[1]=>'B',['key'=>'value'])

array_search ve in_array () burada çalışmadığından belirtilenleri etkili bir şekilde bulmak için. Ve unset () ile bir şeyler kaldırmak .

Sanırım birine yardım edecek.


0

Belirli Dizi değerini silme ile sayısal dizi oluşturma

    <?php
    // create a "numeric" array
    $animals = array('monitor', 'cpu', 'mouse', 'ram', 'wifi', 'usb', 'pendrive');

    //Normarl display
    print_r($animals);
    echo "<br/><br/>";

    //If splice the array
    //array_splice($animals, 2, 2);
    unset($animals[3]); // you can unset the particular value
    print_r($animals);

    ?>

Bu bağlantıya başvurabilirsiniz ..


Downvote. Soru açıkça değere göre bir değeri kaldırmayı ister (anahtarı değil). Bu cevap işe yaramaz, lütfen silin.
mickmackusa

0
$remove= "strawberry";
$array = ["apple", "orange", "strawberry", "blueberry", "kiwi"];
foreach ($array as $key => $value) {
        if ($value!=$remove) {
        echo $value.'<br/>';
                continue;
        }
}

Bu cevap gerekli seçeneği bile kaldırmıyor.
Nigel Ren

-1

Düğmesini kullanarak array_seach()aşağıdakileri deneyin:

if(($key = array_search($del_val, $messages)) !== false) {
    unset($messages[$key]);
}

array_search()bu öğeyi kullanarak orijinal diziden kaldırmak için kullanılabilen bulduğu öğenin anahtarını döndürür unset(). FALSEBaşarısızlığa geri dönecektir , ancak başarı üzerine "falsey" değerini döndürebilir (anahtarınız 0örneğin olabilir ), bu yüzden sıkı karşılaştırma!== operatörü kullanılır.

if()İfadesi olmadığını kontrol edecek array_search()bir değer döndü ve yaptım keşke bir eylem gerçekleştirir.


3
Downvote. Bu, sizden yıllar önce yayınlanan Gumbo yönteminin (şu anda kabul edilen çözüm) bir kopyası. Yinelenen cevapların değeri yoktur ve yalnızca gereksiz sayfa şişkinliğine neden olur. Lütfen cevabınızı silin. Gumbo'nun cevabını açıklamak istiyorsanız, cevabında bir düzenleme yapın veya Gumbo'dan kendi cevabını genişletmesini isteyin ..
mickmackusa

-1
unset($array[array_search('strawberry', $array)]);

2
Downvote. array_search()- unset()yöntem zaten seninkinden önce John Conde yıllar tarafından gönderilmiştir. Yinelenen cevapların okuyucular için bir değeri yoktur ve gereksiz bilgileri kaydırırken ve okurken zaman kaybı nedeniyle aslında bir rahatsızlıktır. Lütfen bu yanıtı silin.
mickmackusa

-1
<?php 
$array = array("apple", "orange", "strawberry", "blueberry", "kiwi");
$delete = "strawberry";
$index = array_search($delete, $array);
array_splice($array, $index, 1);
var_dump($array);
?>

2
A) kodun ne yaptığına ve b) neden diğer tüm cevaplar arasında bir seçenek olduğunu düşündüğünüze dair bir veya iki cümle yazarak bu yanıtı geliştirebilirsiniz.
Robin Mackenzie

-1
foreach ($get_dept as $key5 => $dept_value) {
                if ($request->role_id == 5 || $request->role_id == 6){
                    array_splice($get_dept, $key5, 1);
                }
            }

4
Verdiğiniz yanıta ek olarak, lütfen bunun neden ve nasıl sorunu çözdüğüne dair kısa bir açıklama sağlayın.
jtate

-2
$detils = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
     function remove_embpty($values)
     {
        if($values=='orange')
        {
            $values='any name';
        }
        return $values;
     }
     $detils=array_map('remove_embpty',$detils);
    print_r($detils);

2
Lütfen açıklama ekleyin. Sorunu nasıl çözdüğü.
Rahil Wazir

cevabınız, bir elemanı kaldırmak için dizi elemanını başka bir NO ile değiştirir
ahmed hamdy

Downvote. Bu cevap beklenen çıktıyı sağlamaz. Lütfen bu yanlış yanıtı silin.
mickmackusa
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.