PHP Удалить элементы из ассоциативного массива


100

У меня есть массив PHP, который выглядит примерно так:

Index              Key     Value
[0]                1       Awaiting for Confirmation
[1]                2       Assigned
[2]                3       In Progress
[3]                4       Completed
[4]                5       Mark As Spam

Когда я var_dump значения массива, я получаю следующее:

array(5) { [0]=> array(2) { ["key"]=> string(1) "1" ["value"]=> string(25) "Awaiting for Confirmation" } [1]=> array(2) { ["key"]=> string(1) "2" ["value"]=> string(9) "Assigned" } [2]=> array(2) { ["key"]=> string(1) "3" ["value"]=> string(11) "In Progress" } [3]=> array(2) { ["key"]=> string(1) "4" ["value"]=> string(9) "Completed" } [4]=> array(2) { ["key"]=> string(1) "5" ["value"]=> string(12) "Mark As Spam" } }

Я хотел удалить " Завершено" и " Пометить как спам" . Я знаю, что могу unset[$array[3],$array[4]), но проблема в том, что иногда порядковый номер может быть другим.

Есть ли способ удалить их, сопоставив имя значения вместо значения ключа?


Не уверен, понимаю ли я рассматриваемый здесь вопрос? Что значит иногда порядковый номер может быть другим?
Simon H

Ответы:


153

Ваш массив довольно странный: почему бы просто не использовать keyas index, а valueas ... значение?

Не было бы намного проще, если бы ваш массив был объявлен так:

$array = array(
    1 => 'Awaiting for Confirmation', 
    2 => 'Asssigned', 
    3 => 'In Progress', 
    4 => 'Completed', 
    5 => 'Mark As Spam', 
);

Это позволит вам использовать ваши значения в keyкачестве индексов для доступа к массиву ...

И вы сможете использовать функции для поиска значений, например array_search():

$indexCompleted = array_search('Completed', $array);
unset($array[$indexCompleted]);

$indexSpam = array_search('Mark As Spam', $array);
unset($array[$indexSpam]);

var_dump($array);

Проще, чем с вашим массивом, не так ли?



Вместо этого с вашим массивом, который выглядит так:

$array = array(
    array('key' => 1, 'value' => 'Awaiting for Confirmation'), 
    array('key' => 2, 'value' => 'Asssigned'), 
    array('key' => 3, 'value' => 'In Progress'), 
    array('key' => 4, 'value' => 'Completed'), 
    array('key' => 5, 'value' => 'Mark As Spam'), 
);

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

foreach ($array as $index => $data) {
    if ($data['value'] == 'Completed' || $data['value'] == 'Mark As Spam') {
        unset($array[$index]);
    }
}
var_dump($array);

Даже если это возможно, все не так просто ... и я настаиваю: нельзя ли изменить формат вашего массива, чтобы работать с более простой системой ключ / значение?


«Вам придется перебрать все элементы, чтобы проанализировать ценность». Когда вы используете array_search, вы также можете искать по всем элементам.
Николас Аоки


16
$key = array_search("Mark As Spam", $array);
unset($array[$key]);

Для 2D-массивов ...

$remove = array("Mark As Spam", "Completed");
foreach($arrays as $array){
    foreach($array as $key => $value){
        if(in_array($value, $remove)) unset($array[$key]);
    }
}


3

Почему не использовать array_diff?

$array = array(
    1 => 'Awaiting for Confirmation', 
    2 => 'Asssigned', 
    3 => 'In Progress', 
    4 => 'Completed', 
    5 => 'Mark As Spam', 
);
$to_delete = array('Completed', 'Mark As Spam');
$array = array_diff($array, $to_delete);

Просто обратите внимание, что ваш массив будет переиндексирован.


1

Попробуй это:

$keys = array_keys($array, "Completed");

/ edit Как упоминалось JohnP, этот метод работает только для невложенных массивов.


0

Способ сделать это - взять ваш вложенный целевой массив и скопировать его за один шаг во невложенный массив. Удалите ключ (и), а затем назначьте окончательный обрезанный массив вложенному узлу более раннего массива. Вот код для упрощения:

$temp_array = $list['resultset'][0];

unset($temp_array['badkey1']);
unset($temp_array['badkey2']);

$list['resultset'][0] = $temp_array;

0

Я не согласен с принятым ответом. Иногда архитектура приложения не хочет, чтобы вы возились с идентификатором массива, или делает это неудобным. Например, я довольно часто использую CakePHP, и запрос к базе данных возвращает первичный ключ как значение в каждой записи, очень похожее на приведенное выше.

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

Хотя это может показаться неэффективным, на самом деле в наши дни очень модно иметь неизменяемые переменные, и тот факт, что большинство функций массива php возвращают новый массив, а не заигрывают с оригиналом, подразумевает, что PHP вроде как хочет, чтобы вы тоже это делали. И чем больше вы работаете с массивами и понимаете, насколько сложна и раздражает функция unset (), этот подход приобретает большой смысл.

Тем не мение:

$my_array = array_filter($my_array, 
                         function($el) { 
                            return $el["value"]!="Completed" && $el!["value"]!="Marked as Spam"; 
                         });

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


-1

для использования одного элемента массива reset($item)


Функцию сброса следует использовать для перемещения указателя внутреннего массива, а не для удаления элементов или сброса элементов из массива. Вместо этого используйте unset. Если ваше решение даже работает, оно также имеет нежелательные побочные эффекты.
Дэвид
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.