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.