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.