Як видалити елемент масиву в циклі foreach?


127

Я хочу провести цикл через масив, foreachщоб перевірити, чи існує значення. Якщо значення існує, я хочу видалити елемент, який його містить.

У мене є такий код:

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

Я не знаю, як видалити елемент, як тільки знайдено значення. Як її видалити?

Мені доводиться використовувати foreachдля цієї проблеми. Ймовірно, є альтернативи foreach, і ви можете їм поділитися.

Відповіді:


220

Якщо ви також отримаєте ключ, ви можете видалити цей елемент так:

foreach ($display_related_tags as $key => $tag_name) {
    if($tag_name == $found_tag['name']) {
        unset($display_related_tags[$key]);
    }
}

3
Деякі додаткові відомості про оптимізацію за допомогою $key => &$tag_name stackoverflow.com/a/2008893/922522
— Джастін

5
Зауважте, що індексовані масиви з вимкненими елементами можуть бути представлені у вигляді об'єктів замість масивів після а json_encode(). Ви можете вирішити це $display_related_tags = array_values ($display_related_tags);за допомогою foreachциклу.
— Márton Tamás

Зауважте, у цьому полягає хитрість - додати значення циклу foreach ;-)
— Містер Вашингтон

5
Дивіться відповідь @Neils. У вас виникнуть несподівані помилки, особливо якщо ви працюєте з масивом stdClasses. Вам подобається несподівана поведінка? Я ні.
— happy_marmoset

@happy_marmoset Нілс відповідь не допомагає. Знімок, який $projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });він перетворює, призводить до об'єкта.
— Парітош

36

Кращим рішенням є використання 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 не використовує внутрішній покажчик масиву.


Зауважте, що 3-й параметр повинен бути ARRAY_FILTER_USE_KEY, щоб передати ключ тут як $ e.
— namezero

@namezero ОК, чому це тут важливо?
— AbraCadaver

@AbraCadaver З документації ( php.net/manual/en/function.array-filter.php ): ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value Default is 0 which will pass value as the only argument to callback instead. Це сказало, прочитавши відповідь ще раз у цьому випадку, звичайно, це не матиме значення, як ви заявляєте.
— namezero

Важливо Якщо ви хочете зберегти масив як упорядкований масив, вам потрібно зателефонувати display_related_tags = array_values(display_related_tags);після нього.
— guyaloni

9
foreach($display_related_tags as $key => $tag_name)
{
    if($tag_name == $found_tag['name'])
        unset($display_related_tags[$key];
}

3
'unlink' від’єднує файли, це не має нічого спільного зі змінними або, точніше, масивами. Можливо, ви маєте на увазі «невдалий»?
— amn

6

Замість того, щоб робити цикл foreach () на масиві, було б швидше скористатися array_search () для пошуку потрібного ключа. На малих масивах я б хотів з foreach для кращої читальності, але для більших масивів або часто виконуваного коду це має бути трохи більш оптимальним:

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

Необхідний суворий оператор порівняння! ==, тому що array_search () може повернути 0 як індекс $ neželjeноїValue.

Крім того, вищенаведений приклад видалить лише перше значення $ neželjeноїValue, якщо $ unantedValue може виникнути більше, ніж один раз у масиві $, слід знайти 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

якщо у вас є сценарій, у якому вам доведеться видалити більше, ніж одне значення з масиву 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

Вже є відповіді, які висвітлюють, як зняти налаштування. Замість того, щоб повторювати код у всіх класах, виконайте функцію, як показано нижче, та використовуйте її в коді, коли це потрібно. У бізнес-логіці іноді не хочеться викривати деякі властивості. Щоб видалити, перегляньте нижче один виклик лайнера

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);

-1

Як уже згадувалося, ви хочете зробити передбачення з ключем і скасувати використання ключа, але зауважте, що мутація масиву під час ітерації - це погана ідея, хоча я не впевнений у правилах PHP щодо цього віддалено.


2
Незалежно від цілого масиву виконуватиметься php foreach. Перевірте встановлення значення, наступного за ітерацією. Він буде повторюватись при зміщенні, але значення буде нульовим.
— Кевін Пено

Якщо ви не мутуєте масив під час ітерації, то як взагалі мутувати масив? Можуть бути середніми foreachчи forконструкціями замість ітерації взагалі?
— Герман

Це скоріше коментар до іншої відповіді, ніж відповідь сама по собі.
— Зловісна Борода
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.