PHP: Як видалити конкретний елемент з масиву?


160

Як видалити елемент із масиву, коли я знаю ім'я елементів? наприклад:

У мене є масив:

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

користувач входить strawberry

strawberry видаляється.

Щоб повністю пояснити:

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



1
Ще одне і те ж питання: stackoverflow.com/questions/1883421/…
Ерік Лавуа

1
ще те саме питання: stackoverflow.com/questions/369602/…
Олексій

Відповіді:


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буде переписано.)
Gumbo

я оновив своє запитання, щоб краще пояснити. В основному код проходить цикл через записи в базі даних, видаляючи обрані елементи, "полуниця" в цьому прикладі. Отже, користувач вводить select => код шукає у підменю та знаходить будь-який список, у якого є ця опція => перетворює цей список у масив => видаляє обраний параметр.
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
Ви повинні перевірити, чи є полуниця взагалі в масиві.
Гумбо

Дотримуючись поради Gumbo, видозмінений відповідь, щоб включити перевірку елемента перед його видаленням з масиву.
Джон Конде

2
Також пам’ятайте, що індекси не вирівнюються після видалення певного елемента. Іншими словами, індексна послідовність матиме прогалини тоді. Якщо ви видалите 'полуницю' зі свого прикладу, 'kiwi' все одно матиме індекс 4, а індекс 2 просто зникне. Має значення, чи ваш код покладається на повноту послідовності індексу, як це робиться, наприклад, для циклів ($ i = 0; $ i <.., $ i ++).
король-банан

2
Щоб додати те, що сказав король-банан, якщо ви хочете перевстановити масив, просто зробіть це $my_array = array_values($my_array);.
ryeguy

2
Хоча це рішення правильне, він шукає масив TWICE ( in_arrayі array_search). Використання повернення array_searchяк у відповіді Гумбо є більш ефективним
Богдан Д

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']

Порівняно з вимкненим:

$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]))не підходить для порівняння.
robsch

це саме те, що мені потрібно, thaks to ericluwj
ana

12

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

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

Downvote. Ця низька якість (оскільки це лише відповідь на код і дає помилку при розборі) - це дублікат методу Д.Мартіна, який просто використовує анонімну функцію всередині array_filter(). Хоча я особисто використовував анонімну функцію у своїй реалізації, я вважаю, що правильною дією щодо SO було б прокоментувати або відредагувати відповідь Д.Мартіна, якщо ви хочете зробити мікрополіпшення, щоб ця сторінка не розгорнулася. Видаліть цю повторювану відповідь.
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(). Як це отримало три оновлення. Ніхто не повинен вважати цю відповідь корисною або використовувати її у власних проектах. Рекомендую видалити цю відповідь - це допоможе звільнити ваш обліковий запис неякісної відповіді, зменшити кількість відповідей на цій сторінці та заробити вам знак дисциплінованості. Я відкладу свій нижчий запис, щоб у вас був час видалити на винагороду.
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

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

Сподіваюся, це допоможе


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. Це дублікат методу Гумбо (зараз прийняте рішення), який був розміщений за роки до вашого. Повторювані відповіді не мають значення і викликають лише непотрібне роздуття сторінки. Видаліть свою відповідь. Якщо ви хочете пояснити відповідь Gumbo, зробіть це за допомогою редагування його відповіді або попросіть Gumbo розширити власну відповідь ..
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.