Удаление элемента массива по значению

Ответы:

423

Это может быть достигнуто с простым однострочником.

Имея этот массив:

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

Ты можешь сделать:

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

И стоимость $arrбудет:

array('nice_item', 'another_liked_item')

Надеюсь, это поможет написать красивый код.

Алехандро Гарсия Иглесиас
источник
2
Нет, это делает работу с ссылочными массивами, то array_diffфункция является неразрушающей, он возвращает новый массив.
Алехандро Гарсия Иглесиас
2
@srcspider почему бы и нет? $referenced = array_diff($referenced, $items_to_remove);
Алехандро Гарсия Иглесиас
1
$ referenced теперь указывает на новый массив, массив, который вы хотите изменить, все еще имеет старые значения.
srcspider
2
@ srcspider, расскажи мне, что здесь происходит ... codepad.org/11ZhiFP0
Алехандро Гарсия Иглесиас
1
моя вина; трюк с псевдонимами в переменной php всегда
сбивает
37

Я добавляю второй ответ. Я написал скрипт быстрого бенчмаркинга, чтобы попробовать различные методы здесь.

$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()с указанием необязательного параметра поиска, похоже, является наилучшим. Пример вывода:

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

Судя по этому, решение, которое я бы использовал тогда, было бы:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}
zombat
источник
Я думаю, что array_search - намного более читаемый код, чем использование метода array_diff. Upvote
kendepelchin
@zombat Интересно, имеет ли порядок какое-либо отношение к результатам. Возможно, что shuffle поместит искомое значение ближе к фронту или к концу. Кроме этого ... +1
Генерал Реднек
31

Как насчет:

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

или для нескольких значений:

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

Это также предотвратит потерю ключа, что является побочным эффектом array_flip().

zombat
источник
1
не будет работать, если $ id - первый элемент массива, лучше так: if (($ key = array_search ($ id, $ items))! == false) unset ($ items [$ key]);
Марек
15

удалить $rm_valиз$arr

unset($arr[array_search($rm_val, $arr)]);
Toma
источник
8

Наиболее мощным решением будет использование array_filter, которое позволяет вам определить свою собственную функцию фильтрации.

Но некоторые могут сказать, что это немного излишне, в вашей ситуации ...
Простого foreachцикла, чтобы пройти массив и удалить ненужный элемент, должно быть достаточно.

Что-то вроде этого в вашем случае, вероятно, должно сработать:

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

Попробуйте array_search ()

Savageman
источник
3
Я просто прочитал документацию и рекомендую использовать array_keys (), чтобы найти все ключи, связанные со значением.
Savageman
@ Savageman - Согласен. Я провел быстрый тест и, array_keys()кажется, работает лучше, чем array_search()для этой задачи.
зомбат
6

Ваши решения работают, только если у вас есть уникальные значения в вашем массиве

Видеть:

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

Лучший способ был бы не установлен с array_search , в цикле, если это необходимо.

Dutow
источник
Вы правы, но в данном конкретном случае я почти уверен, что значения уникальны :)
Marek
5

без флип:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}
erenon
источник
5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}
Суман Бисвас
источник
4

Вы можете использовать функцию array_splice для этой операции Ref: array_splice

array_splice($array, array_search(58, $array ), 1);
Техас Сони
источник