How to unset (remove) a collection element after fetching it?

LaravelCollections

Laravel Problem Overview


I have a collection which I want to iterate and modify while I fetch some of its elements. But I could't find a way or method to remove that fetched element.

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

This is just a representation of my question for demonstration.

After @Ohgodwhy advice the forget() function I checked it again and saw that I actually misunderstood the function. It was exactly as I was looking for.

So for working solution I have added $collection->forget($key) inside the if statement.

Below is the working solution of my problem, using @Ohgodwhy's solution:

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

(this is just a demonstration)

Laravel Solutions


Solution 1 - Laravel

You would want to use ->forget()

$collection->forget($key);

Link to the forget method documentation

Solution 2 - Laravel

Or you can use reject method

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

or pull method

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

Solution 3 - Laravel

Laravel Collection implements the PHP ArrayAccess interface (which is why using foreach is possible in the first place).

If you have the key already you can just use PHP unset.

I prefer this, because it clearly modifies the collection in place, and is easy to remember.

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

Solution 4 - Laravel

I'm not fine with solutions that iterates over a collection and inside the loop manipulating the content of even that collection. This can result in unexpected behaviour.

See also here: https://stackoverflow.com/a/2304578/655224 and in a comment the given link http://php.net/manual/en/control-structures.foreach.php#88578

So, when using foreach it seems to be ok but IMHO the much more readable and simple solution is to filter your collection to a new one.

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

Solution 5 - Laravel

> If you know the key which you unset then put directly by comma > separated

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

Solution 6 - Laravel

You can use methods of Collection like pull, forget, reject etc.

But every Collection method returns an entirely new Collection instance.

Doc link: https://laravel.com/docs/8.x/collections#introduction

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSkeletorView Question on Stackoverflow
Solution 1 - LaravelOhgodwhyView Answer on Stackoverflow
Solution 2 - LaravelhuuukView Answer on Stackoverflow
Solution 3 - LaravelandrewtweberView Answer on Stackoverflow
Solution 4 - LaravelalgorhythmView Answer on Stackoverflow
Solution 5 - LaravelKaushik shrimaliView Answer on Stackoverflow
Solution 6 - LaravelAli Akbar AfridiView Answer on Stackoverflow