Как удалить элемент массива в цикле foreach? - PullRequest
107 голосов
/ 23 декабря 2009

Я хочу перебрать массив с foreach, чтобы проверить, существует ли значение. Если значение существует, я хочу удалить содержащий его элемент.

У меня есть следующий код:

foreach($display_related_tags as $tag_name) {
    if($tag_name == $found_tag['name']) {
        // Delete element
    }
}

Я не знаю, как удалить элемент, когда значение найдено. Как мне его удалить?

Я должен использовать foreach для этой проблемы. Вероятно, есть альтернативы foreach, и вы можете поделиться ими.

Ответы [ 8 ]

189 голосов
/ 23 декабря 2009

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

foreach ($display_related_tags as $key => $tag_name) {
    if($tag_name == $found_tag['name']) {
        unset($display_related_tags[$key]);
    }
}
26 голосов
/ 09 августа 2016

Лучшим решением является использование функции array_filter:

$display_related_tags =
    array_filter($display_related_tags, function($e) use($found_tag){
        return $e != $found_tag['name'];
    });

Как документация php гласит:

Поскольку foreach полагается на внутренний указатель массива в PHP 5, его изменение в цикле может привести к неожиданному поведению.

В PHP 7 foreach не использует внутренний указатель массива.

9 голосов
/ 23 декабря 2009
foreach($display_related_tags as $key => $tag_name)
{
    if($tag_name == $found_tag['name'])
        unset($display_related_tags[$key];
}
6 голосов
/ 23 декабря 2009

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

$result=array_search($unwantedValue,$array,true);
if($result !== false) {
  unset($array[$result]);   
}

Требуется оператор строгого сравнения! ==, поскольку array_search () может возвращать 0 в качестве индекса $ unwantedValue.

Кроме того, приведенный выше пример удалит только первое значение $ unwantedValue, если $ unwantedValue может встречаться в массиве $ более одного раза, вы должны использовать array_keys (), чтобы найти их все:

$result=array_keys($array,$unwantedValue,true)
foreach($result as $key) {
  unset($array[$key]);
}

Проверьте http://php.net/manual/en/function.array-search.php для получения дополнительной информации.

0 голосов
/ 26 декабря 2017

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

public static function removeKeysFromAssociativeArray($associativeArray, $keysToUnset)
{
    if (empty($associativeArray) || empty($keysToUnset))
        return array();

    foreach ($associativeArray as $key => $arr) {
        if (!is_array($arr)) {
            continue;
        }

        foreach ($keysToUnset as $keyToUnset) {
            if (array_key_exists($keyToUnset, $arr)) {
                unset($arr[$keyToUnset]);
            }
        }
        $associativeArray[$key] = $arr;
    }
    return $associativeArray;
}

Звоните как:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);
0 голосов
/ 10 декабря 2015

если у вас есть сценарий, в котором вам нужно удалить более одного значения из массива foreach, в этом случае вы должны передать значение по ссылке для каждого: Я пытаюсь объяснить этот сценарий:

foreach ($manSkuQty as $man_sku => &$man_qty) {

               foreach ($manufacturerSkus as $key1 => $val1) {

  // some processing here and unset first loops entries                     
 //  here dont include again for next iterations
                           if(some condition)
                            unset($manSkuQty[$key1]);

                        }
               }
}

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

0 голосов
/ 27 августа 2012

Попробуйте использовать функции next(), current() в цикле while, for.

0 голосов
/ 23 декабря 2009

Как уже упоминалось, вы хотите выполнить foreach с ключом и сбросить его с помощью ключа - но учтите, что изменение массива во время итерации - это вообще плохая идея, хотя я не уверен в PHP правила в этом случае.

...