Dizi öğesini değere göre kaldırma


Yanıtlar:


423

Basit bir astar ile gerçekleştirilebilir.

Bu diziye sahip olmak:

$arr = array('nice_item', 'remove_me', 'another_liked_item', 'remove_me_also');

Yapabilirsin:

$arr = array_diff($arr, array('remove_me', 'remove_me_also'));

Ve değeri $arr:

array('nice_item', 'another_liked_item')

Umarım güzel kod yazmaya yardımcı olur.


2
Hayır, yok başvurulan diziler eserler, array_difffonksiyon yeni bir dizi döndürür, tahribatsız olduğunu.
Alejandro García Iglesias

2
@srcspider neden olmasın? $referenced = array_diff($referenced, $items_to_remove);
Alejandro García Iglesias

1
$ reference artık yeni bir diziyi işaret ediyor, değiştirmek istediğiniz dizi hala eski değerlere sahip.
srcspider

2
@srcspider iyi, bana burada neler olduğunu söyle ... codepad.org/11ZhiFP0
Alejandro García Iglesias

1
benim hatam; php değişken aliasing hile her zaman beni
gezdiriyor

37

İkinci bir cevap ekliyorum. Burada çeşitli yöntemleri denemek için hızlı bir karşılaştırma senaryosu yazdım.

$arr = array(0 => 123456);
for($i = 1; $i < 500000; $i++) {
    $arr[$i] = rand(0,PHP_INT_MAX);
}

shuffle($arr);
$arr2 = $arr;
$arr3 = $arr;

/** 
 * Method 1 - array_search()
 */
$start = microtime(true);
while(($key = array_search(123456,$arr)) !== false) {
    unset($arr[$key]);
}
echo count($arr). ' left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 2 - basic loop
 */
$start = microtime(true);
foreach($arr2 as $k => $v) {
    if ($v == 123456) {
        unset($arr2[$k]);
    }
}
echo count($arr2). 'left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 3 - array_keys() with search parameter
 */
$start = microtime(true);
$keys = array_keys($arr3,123456);
foreach($keys as $k) {
    unset($arr3[$k]);
}
echo count($arr3). 'left, in '.(microtime(true) - $start).' seconds<BR>';

array_keys()İsteğe bağlı arama parametresinin belirtildiği üçüncü yöntem, açık ara en iyi yöntem gibi görünmektedir. Çıktı örneği:

499999 left, in 0.090957164764404 seconds
499999left, in 0.43156313896179 seconds
499999left, in 0.028877019882202 seconds

Buna bakarak, o zaman kullanacağım çözüm:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}

Dizi_search dizi_diff yöntemini kullanmaktan çok daha okunabilir kod olduğunu düşünüyorum. Olumlu oy
kendepelchin

@zombat Siparişin sonuçlarla bir ilgisi olup olmadığını merak ediyorum. Shuffle'ın aradığımız değeri öne veya sonuna yaklaştırması mümkündür. Bunun dışında ... +1
General Redneck

31

Nasıl olur:

if (($key = array_search($id, $items)) !== false) unset($items[$key]);

veya birden çok değer için:

while(($key = array_search($id, $items)) !== false) {
    unset($items[$key]);
}

Bu da anahtar kaybını önleyecektir, ki bu da bir yan etkisidir array_flip().


1
$ id ilk dizi elemanıysa çalışmaz, bu şekilde daha iyi: if (($ key = array_search ($ id, $ items))! == false) unset ($ items [$ key]);
Marek

15

kaldırmak için $rm_valgelen$arr

unset($arr[array_search($rm_val, $arr)]);

8

En güçlü çözüm array_filter, kendi filtreleme işlevinizi tanımlamanızı sağlar.

Ama bazıları sizin durumunuzda biraz abartılı olduğunu söyleyebilir ... Diziye girip istemediğiniz öğeyi kaldırmak için
basit bir foreachdöngü yeterli olmalıdır.

Böyle bir şey, sizin durumunuzda, muhtemelen hile yapmalıdır:

foreach ($items as $key => $value) {
    if ($value == $id) {
        unset($items[$key]);
        // If you know you only have one line to remove, you can decomment the next line, to stop looping
        //break;
    }
}

6

3
Ben sadece belgeleri okumak ve bir değerle ilişkili tüm anahtarları bulmak için array_keys () kullanmanızı öneririz.
Savageman

@ Savaveman - Kabul etti. Hızlı bir kıyaslama yaptım ve bu görevden array_keys()daha iyi performans gösterdim array_search().
zombat

6

Çözümleriniz yalnızca dizinizde benzersiz değerler varsa çalışır

Görmek:

<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>

Daha iyi bir yol ile unset olacağını array_search gerekli ise bir döngü içinde.


haklısın, ama bu özel durumda değerlerin benzersiz olduğundan eminim :)
Marek

5

kapaksız:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}

5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}

4

Bu işlem için array_splice işlevini kullanabilirsiniz Ref: array_splice

array_splice($array, array_search(58, $array ), 1);
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.