PHP: Как удалить конкретный элемент из массива?


160

Как удалить элемент из массива, когда я знаю имя элемента? например:

У меня есть массив:

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

пользователь вводит strawberry

strawberry устранен.

Чтобы полностью объяснить:

У меня есть база данных, в которой хранится список элементов, разделенных запятой. Код загружается в список на основе выбора пользователя, где этот выбор находится. Таким образом, если они выбирают «клубнику», они извлекают код в каждой записи, где находится «клубника», а затем преобразуют ее в массив с помощью split (). Я хочу, чтобы они удалили выбранные пользователем элементы, например, для клубники, из массива.


4
Тот же вопрос: stackoverflow.com/questions/7225070/…
— Trante

1
Еще один и тот же вопрос: stackoverflow.com/questions/1883421/…
— Эрик Лавуа

1
еще один и тот же вопрос: stackoverflow.com/questions/369602/…
— Alex

Ответы:


296

Используйте, array_searchчтобы получить ключ и удалить его, unsetесли он найден:

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

array_searchвозвращает false ( ноль до PHP 4.2.0), если элемент не был найден.

И если может быть несколько элементов с одинаковым значением, вы можете использовать, array_keysчтобы получить ключи ко всем элементам:

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

Получаю странный результат. Я использовал ваше первое предложение, так как всегда будет только один экземпляр. Чтобы проверить это, я просто вывел значение ключа. Работал. Тем не менее, это не сброшено.
— dcp3450

1
while (odbc_fetch_row ($ runqueryGetSubmenus)) {$ submenuList = odbc_result ($ runqueryGetSubmenus, "подменю"); $ submenuArray = split (',', $ submenuList); if (($ key = array_search ($ name, $ submenuArray))! == false) {unset ($ submenuArray [$ key]); }}
— dcp3450

@ dcp3450: А чем вы занимаетесь $submenuArray? (Обратите внимание, что с каждым циклом $submenuArrayбудут перезаписаны.)
— Гамбо

я обновил свой вопрос, чтобы лучше объяснить. В основном код перебирает записи в базе данных, удаляя выбранные элементы, в данном примере «клубнику». Таким образом, пользователь вводит выбор => код ищет в подменю и находит любой список, который имеет эту опцию => превращает этот список в массив => удаляет выбранную опцию.
— dcp3450

1
Я понял! Я не переписывал новый массив обратно в БД. Легко пропустить вещи, когда вы так долго смотрите на код.
— dcp3450

153

Используйте array_diff()для решения 1 линии:

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

... Нет необходимости в дополнительных функциях или цикле foreach.


8
Это решение более разборчиво, чем верхние.
— Роберт

Хотя если strawberryего нет в исходном массиве, он станет доступным в $array_without_strawberriesмассиве - опасный код, если вы хотите убедиться, что данный элемент не находится в массиве.
— Эрфан

5
@ Erfan Ваше заявление неверно. $a = array_diff(array(), array('strawberry'));- $ a это пустой массив.
— bancer

1
Вы правы @bancer - я, наверное, думал о array_intersect или о чем-то подобном.
— Эрфан

1
array_diff () более элегантна, чем помеченный ответ.
— Дом Дафонте

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

2
Вы должны проверить, есть ли клубника в массиве вообще.
— Гамбо

Следуя совету Гамбо, изменили ответ, включив проверку элемента перед его удалением из массива.
— Джон Конде

2
Также имейте в виду, что индексы не выравниваются после удаления определенного элемента. Другими словами, последовательность индекса будет иметь пробелы. Если вы удалите «клубнику» из своего примера, «киви» все равно будет иметь индекс 4, а индекс 2 просто исчезнет. Имеет значение, если ваш код полагается на полноту последовательности индекса, как, например, для циклов ($ i = 0; $ i <.., $ i ++).
— банановый король

2
Чтобы добавить к сказанному the-banana-king, если вы хотите переиндексировать массив, просто сделайте $my_array = array_values($my_array);.
— Ryeguy

2
Пока это решение корректно, оно ищет массив ДВАЖДЫ ( in_arrayи array_search). Использование возврата array_searchas в ответе Гамбо более эффективно
— Богдан Д.

21

Если вы используете простой массив здесь (что выглядит так), вы должны использовать этот код:

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

unset($array[$key]) только удаляет элемент, но не переупорядочивает обычный массив.

Предположим, у нас есть массив и мы используем array_splice:

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

По сравнению с unset:

$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])не переупорядочивать массив.


Официально unsetничего не возвращает. Так json_encode(unset($array[2]))что не подходит для сравнения.
— робщ

это именно то, что мне нужно, спасибо ericluwj
— ана

12

Вы можете использовать фильтр массива для удаления элементов по определенному условию $v:

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

Downvote. Это низкое качество (потому что это ответ только для кода и дает ошибку синтаксического анализа) является дубликатом метода Д. Мартин, который просто использует внутри анонимную функцию array_filter(). Хотя я лично буду использовать анонимную функцию в своей реализации, я считаю, что правильным действием для SO было бы прокомментировать или отредактировать ответ D.Martin, если вы хотите сделать микро-улучшение, чтобы эта страница не стала раздутой. Пожалуйста, удалите этот дубликат ответа.
— mickmackusa

4

Будет так:

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

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

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

4

Это простое повторение, которое может удалить несколько значений в массиве.

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

Это неэффективная домашняя замена того, что разработчики PHP уже создали array_diff(). Как это получило три голоса. Никто не должен находить этот ответ полезным или использовать его в своих собственных проектах. Я рекомендую удалить этот ответ - это поможет освободить вашу учетную запись от некачественного ответа, уменьшит количество сообщений на этой странице и даст вам значок Disciplined. Я отложу мое понижение, чтобы у вас было время удалить за вознаграждение.
— mickmackusa

4

Просто вы можете сделать одну строку. Это будет удалить элемент из массива


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


3

В настоящее время я использую эту функцию:

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

Вы можете ввести массив или только строку с элементами, которые должны быть удалены. Напишите это так:

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

ИЛИ

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

Это также переиндексирует это.


2
Это ужасно запутанно и странно. Как это получило 3 голоса?!?
— mickmackusa

2

На этот вопрос есть несколько ответов, но я хочу добавить что-то еще, потому что когда я использовал unsetилиarray_diff меня было несколько проблем, чтобы поиграть с индексами нового массива, когда конкретный элемент был удален (потому что первоначальный индекс сохранен)

Вернусь к примеру:

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

или

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

Если вы напечатаете результат, вы получите:

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

Результат:

> apple
> orange
> blueberry
> kiwi

Но индексы будут сохранены, и вы получите доступ к вашему элементу, например:

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

И поэтому окончательный массив не переиндексируется. Так что вам нужно добавить после unsetили array_diff:

$array_without_strawberries = array_values($array);

После этого ваш массив будет иметь нормальный индекс:

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

Связанные с этим постом: Re-Index Array

введите описание изображения здесь

Надеюсь, это поможет


1

Возможно, лучшим подходом было бы сохранить ваши значения в качестве ключей в ассоциативном массиве, а затем вызывать array_keys()его, когда вы хотите получить реальный массив. Таким образом, вам не нужно использовать, array_searchчтобы найти свой элемент.


1
Ваш пост является комментарием, а не ответом. Пожалуйста, удалите и разместите под вопросом.
— mickmackusa

1

Ответ на PHP массив удалить по значению (не ключу) Предоставлено https://stackoverflow.com/users/924109/rok-kralj

ИМО - лучший ответ, поскольку он удаляет и не мутирует

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

Это хорошо обобщает, вы можете удалить столько элементов, сколько хотите одновременно, если хотите.

Отказ от ответственности: обратите внимание, что мое решение создает новую копию массива, сохраняя при этом старый нетронутым в отличие от принятого ответа, который изменяется. Это может быть немного медленнее из-за этого.


1

Я искал ответ на тот же вопрос и наткнулся на эту тему. Я вижу два основных способа: сочетание array_search& unsetи использование array_diff. На первый взгляд мне показалось, что первый метод будет быстрее, так как не требует создания дополнительного массива (как при использованииarray_diff ). Но я написал небольшой тест и убедился, что второй метод не только более лаконичен, но и быстрее! Рад поделиться с вами этим. :)

https://glot.io/snippets/f6ow6biaol


0

Я бы предпочел использовать array_key_exists для поиска ключей в массивах, таких как:

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

эффективно найти указанное, так как array_search и in_array () здесь не работают. И сделать удаление вещи с помощью unset () .

Я думаю, что это поможет кому-то.


0

Создать числовой массив с удалением определенного значения массива

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

    ?>

Вы можете обратиться по этой ссылке ..


Downvote. Вопрос ясно просит удалить значение, основанное на значении (а не ключе). Этот ответ бесполезен, пожалуйста, удалите.
— mickmackusa


-1

Используя array_seach(), попробуйте следующее:

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

array_search()возвращает ключ найденного элемента, который можно использовать для удаления этого элемента из исходного массива с помощью unset(). Он вернется FALSEпри неудаче, однако может вернуть значение «фальси» в случае успеха (ваш ключ может быть, 0например), именно поэтому используется !==оператор строгого сравнения .

Оператор if()проверит, array_search()вернулось ли значение, и выполнит действие, только если он это сделал.


3
Downvote. Это дубликат метода Гамбо (в настоящее время принятого решения), который был опубликован за много лет до вашего. Дублирующиеся ответы не имеют значения и вызывают только ненужное раздувание страницы. Пожалуйста, удалите свой ответ. Если вы хотите объяснить ответ Гамбо, сделайте это с изменениями в его ответе или попросите Гамбо расширить свой собственный ответ ..
— mickmackusa

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

2
Downvote. array_search()- unset()метод уже отвечал Джон Conde лет до твоего. Повторяющиеся ответы не имеют значения для читателей и на самом деле доставляют неудобства из-за потери времени при прокрутке и чтении избыточной информации. Пожалуйста, удалите этот ответ.
— 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
Вы можете улучшить этот ответ, написав одно или два предложения о: а) о том, что делает код, и б) о том, почему вы думаете, что это вариант среди всех остальных ответов.
— Робин Маккензи

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

4
В дополнение к ответу, который вы предоставили, рассмотрите краткое объяснение того, почему и как это решает проблему.
— 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
Пожалуйста, также добавьте объяснение. Как это решает проблему.
— Рахиль Вазир

Ваш ответ заменить один элемент массива на другой НЕТ, чтобы удалить элемент
— Ахмед Хэмди

Downvote. Этот ответ не дает ожидаемого результата. Пожалуйста, удалите этот неправильный ответ.
— mickmackusa
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.