Як зняти (видалити) елемент колекції після його отримання?


84

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

$selected = []; 
foreach ($collection as $key => $value) {
      if ($collection->selected == true) {
          $selected[] = $value;
          unset($value);
      }
}

Це лише подання мого запитання для демонстрації.

Після поради @Ohgodwhy функції забування () я ще раз перевірив її і побачив, що насправді неправильно зрозумів функцію. Це було саме так, як я шукав.

Отже, для робочого рішення я додав $collection->forget($key)усередині оператора if.

Нижче наведено робоче рішення моєї проблеми за допомогою рішення @ Ohgodwhy:

$selected = []; 
foreach ($collection as $key => $value) {
      if ($collection->selected == true) {
          $selected[] = $value;
          $collection->forget($key);
      }
}

(це лише демонстрація)


1
Я пропоную не зберігати ваші предмети в масиві, а створити нову колекцію та додавати до неї елементи за допомогою push.
Амарнасан

@Amarnasan Як би це було зробити? Зараз мені це не потрібно, але я думаю, що це може знадобитися мені в майбутньому
Чарлі,

подивіться тут: stackoverflow.com/a/58769554/655224 . ваш ifстан $collection->selected == trueне має сенсу. чому перевірки якості selectedцього collectionоб'єкта не з value? якщо властивість дійсно всередині, collectionперевірте це один раз поза вашим циклом.
алгоритм

Відповіді:


129

Ви хотіли б використовувати ->forget()

$collection->forget($key);

Посилання на документацію методу забуття


1
Так, насправді я неправильно зрозумів забути (). я думав, що параметр $ key видаляє всі задані ключі. тепер я зміг використати його прямо у циклі з оператором if.
Скелетор

20
forget()це круто в порівнянні з delete()або remove(), але пекло, мені довелося приїхати сюди, щоб дізнатись, як видалити предмет :)
Аттіла Фулоп

як щодо того, якщо ви хочете видалити весь об’єкт?
Chaudhry Waqas

5
@Adamnick З forgetвам потрібно було б знати indexоб'єкт у масиві. Те, що ти хочеш, це, мабуть,filter()
Ohgodwhy,

Для тих, хто дивиться на це зараз, посилання в оригінальному запитанні порушено, але ви можете знайти ту саму документацію тут laravel.com/docs/5.8/collections#method-forget
Bryce Meyer

25

Або ви можете використовувати reject метод

$newColection = $collection->reject(function($element) {
    return $item->selected != true;
});

або pull метод

$selected = []; 
foreach ($collection as $key => $item) {
      if ($item->selected == true) {
          $selected[] = $collection->pull($key);
      }
}

1
Але рішення відхилення не призведе до вилучення елементів із початкової колекції, правда?
Амарнасан

Так, він зберігає
цілу

1
Тоді ідеальним рішенням питання було б друге.
Амарнасан

$collection = $collection->reject(...)замінить оригінальну колекцію новою. І $collection->pull(...)це найкраще рішення, на мою думку. Заголовок теми містить ...after fetching it.... Ось що pullробить.
алгоритм

13

Laravel Collectionреалізує ArrayAccessінтерфейс PHP (саме тому використанняforeach в першу чергу можливо).

Якщо у вас вже є ключ, ви можете просто використовувати PHP unset .

Я віддаю перевагу цьому, оскільки він чітко модифікує колекцію на місці та легко запам’ятовується.

foreach ($collection as $key => $value) {
    unset($collection[$key]);
}

3

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

Дивіться також тут: https://stackoverflow.com/a/2304578/655224 та в коментарі дане посилання http://php.net/manual/en/control-structures.foreach.php#88578

Отже, при використанні foreachif, здається, все в порядку, але IMHO набагато більш читабельним і простим рішенням є фільтрація вашої колекції до нової.

/**
 * Filter all `selected` items
 *
 * @link https://laravel.com/docs/7.x/collections#method-filter
 */
$selected = $collection->filter(function($value, $key) {
    return $value->selected;
})->toArray();

0

Якщо ви знаєте ключ, який ви зняли, поставте безпосередньо комами

unset($attr['placeholder'], $attr['autocomplete']);

Я отримав особливий випадок, коли отримав систему переліку предметів, де нове властивість повертається в останній колекції властивостей, а також у колекції без оцінки, яку я всі показую на одній сторінці. Я хочу, щоб ті елементи, які вже є в першому списку, вискочили з другого списку, як це зробити. Пам’ятайте, ви не можете сказати, в якому індексі буде відображатися елемент. Чи можу я зробити щось подібне $collection->forget($item->id) ?
Розробник програмного забезпечення
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.