поиск и удаление следующего массива внутри массива

#php #arrays

#php #массивы

Вопрос:

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

 $items= [{"link": "1ndexample","mime_type": "image"},{"link": "2ndexample","mime_type": "vide"},{"link": "3ndexample","mime_type": "image"},{"link": "4ndexample","mime_type": "image"}]
  

Я хочу найти элементы с video mime_type, а затем удалить следующие элементы.
Например, в приведенном выше коде верните :

 [{"link": "1ndexample","mime_type": "image"},{"link": "2ndexample","mime_type": "vide"},{"link": "4ndexample","mime_type": "image"}]
  

Как я могу это сделать?
Я написал этот код:

 foreach($items as $item){
    if($item['mime_type'] == 'video'){
        unset (next($items));
    }
}
  

Но он возвращает :

Неустранимая ошибка: не удается использовать возвращаемое значение функции в контексте записи в (unset (next($items));)

Комментарии:

1. Каков ваш ожидаемый результат? next() перемещает внутренний указатель на следующий элемент и ничего не возвращает, а unset() ничего не может отменить.

2. Итак, как я могу отменить следующий массив в foreach?

3. Каков ожидаемый результат? Кроме того, это должно быть video вместо vide в вашем примере JSON.

Ответ №1:

Гораздо проще получить доступ и удалить элемент в for цикле:

 <?php
$items = json_decode('[{"link": "1ndexample","mime_type": "image"},{"link": "2ndexample","mime_type": "video"},{"link": "3ndexample","mime_type": "image"},{"link": "4ndexample","mime_type": "image"}]');

for ($i = count($items) - 1; $i > 0; $i--) {
    if ($items[$i-1]->mime_type === 'video') {
        unset($items[$i]);
    }
}

var_dump($items);
  

Комментарии:

1. При удалении элементов в цикле for безопаснее делать это в обратном направлении.

2. @MarkusZeller Хорошая мысль, спасибо. Я соответствующим образом обновил ответ.

3. Спасибо, можете ли вы сказать мне, почему безопаснее делать это в обратном направлении?

4. @Learner231 Потому что вы не сможете прочитать уже удаленный (следующий) элемент. Пример массива [0 => 'video', 1 => 'video', 2 => 'image'] … Первая итерация цикла проверяет, что элемент с индексом 0 равен video и удаляет элемент с индексом 1. Вторая итерация хочет проверить элемент с индексом 1, но он уже удален… Когда вы выполняете цикл в обратном направлении, нет риска получить доступ к уже удаленным элементам.

Ответ №2:

Ваш код работает, если вы используете ключ:

 foreach($items as $key => $item){
    if($item['mime_type'] == 'video'){
        unset($items[$key 1]);
    }
}