Menghapus item array berdasarkan nilai

166

Saya perlu menghapus item array dengan nilai yang diberikan:

if (in_array($id, $items)) {
    $items = array_flip($items);
    unset($items[ $id ]);
    $items = array_flip($items);
}

Bisakah itu dilakukan dengan cara yang lebih pendek (lebih efisien)?

Marek
sumber

Jawaban:

423

Itu dapat dicapai dengan satu-liner sederhana.

Memiliki array ini:

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

Anda dapat melakukan:

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

Dan nilai $arrakan:

array('nice_item', 'another_liked_item')

Semoga ini membantu menulis kode yang indah.

Alejandro García Iglesias
sumber
2
Tidak, ini berfungsi dengan array yang direferensikan, array_difffungsinya non-destruktif, ia mengembalikan array baru.
Alejandro García Iglesias
2
@ srcspider kenapa tidak? $referenced = array_diff($referenced, $items_to_remove);
Alejandro García Iglesias
1
$ direferensikan sekarang menunjuk ke array baru, array yang ingin Anda ubah masih memiliki nilai lama.
srcspider
2
@srcspider yah, katakan padaku apa yang terjadi di sini kemudian ... codepad.org/11ZhiFP0
Alejandro García Iglesias
1
salahku; php's
alias
37

Saya menambahkan jawaban kedua. Saya menulis skrip pembandingan cepat untuk mencoba berbagai metode di sini.

$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>';

Metode ketiga, array_keys()dengan parameter pencarian opsional yang ditentukan, tampaknya sejauh ini merupakan metode terbaik. Contoh keluaran:

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

Menilai dengan ini, solusi yang akan saya gunakan adalah:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}
zombat
sumber
Saya pikir array_search adalah kode yang lebih mudah dibaca daripada menggunakan metode array_diff. Upvote
kendepelchin
@ Zombat Saya ingin tahu apakah pesanan ada hubungannya dengan hasil. Ada kemungkinan bahwa shuffle meletakkan nilai yang kita cari lebih dekat ke depan atau akhir. Selain itu ... +1
Jenderal Redneck
31

Bagaimana tentang:

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

atau untuk beberapa nilai:

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

Ini akan mencegah kehilangan kunci juga, yang merupakan efek samping dari array_flip().

zombat
sumber
1
tidak akan berfungsi jika $ id adalah elemen array pertama, lebih baik dengan cara ini: if (($ key = array_search ($ id, $ items))! == false) tidak disetel ($ items [$ key]);
Marek
15

untuk menghapus $rm_valdari$arr

unset($arr[array_search($rm_val, $arr)]);
Toma
sumber
8

Solusi yang paling kuat akan digunakan array_filter, yang memungkinkan Anda untuk menentukan fungsi penyaringan Anda sendiri.

Tetapi beberapa orang mungkin mengatakan itu sedikit berlebihan, dalam situasi Anda ...
Sebuah foreachloop sederhana untuk melewati array dan menghapus item yang tidak Anda inginkan sudah cukup.

Sesuatu seperti ini, dalam kasus Anda, mungkin harus melakukan trik:

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;
    }
}
Pascal MARTIN
sumber
6

Coba array_search ()

Orang Savageman
sumber
3
Saya baru saja membaca dokumentasi, dan merekomendasikan untuk menggunakan array_keys () untuk menemukan semua kunci yang terkait dengan nilai.
Savageman
@Savageman - Setuju. Saya menjalankan patokan cepat dan array_keys()tampaknya berkinerja lebih baik daripada array_search()untuk tugas ini.
zombat
6

Solusi Anda hanya berfungsi jika Anda memiliki nilai unik dalam array Anda

Lihat:

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

Cara yang lebih baik akan tidak disetel dengan array_search , dalam satu lingkaran jika perlu.

Dutow
sumber
Anda benar, tetapi dalam kasus ini aku cukup yakin bahwa nilai-nilai unik :)
Marek
5

tanpa flip:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}
erenon
sumber
5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}
Suman Biswas
sumber
4

Anda dapat menggunakan fungsi array_splice untuk operasi ini Ref: array_splice

array_splice($array, array_search(58, $array ), 1);
Tejas Soni
sumber