Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Collection prevent null being added to resulting collection with pop and shift #38265

Conversation

craig-sen
Copy link

@craig-sen craig-sen commented Aug 7, 2021

ISSUE

In this PR the ability to pop and shift a specified number of items from a collection was added.
However, if the supplied parameter is outside the bounds of the collection NULL values are added to the end of the collection.

    $collect = collect([1, 2, 3 , 4]);

    $collect->shift(6);

    // collect([1, 2, 3, 4, NULL, NULL])

this is also the same for negative parameters, and for when the collection is empty

changes in this pr

This PR adds checks to the parameter passed to the pop and shift methods and if out of bounds returns only the items in the collection. This is in line with the behaviour of splice and take which do not add null values if the parameter is out of bounds.

return null when the collection is empty and a parameter is passed to the pop() or shift() function

return null when the parameter is less than 1
(throwing an IllegalArgumentException is also a possiblity)

@craig-sen craig-sen marked this pull request as ready for review August 7, 2021 07:27
@craig-sen craig-sen marked this pull request as draft August 7, 2021 11:27
@craig-sen craig-sen force-pushed the prevent_null_being_added_to_pop_and_shift branch from e9d5fa7 to 40ccf2b Compare August 7, 2021 11:43
@craig-sen craig-sen marked this pull request as ready for review August 7, 2021 11:47
@@ -793,10 +793,16 @@ public function only($keys)
*/
public function pop($count = 1)
{
if ($count < 1 || $this->count() === 0) {
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be a new empty collection instead of null to allow for chaining?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just use return;, there are 2 more spots in this file related to the functions median() and mode() which also have a null return. I'm not sure if returning a new collection is appropriate here when comparing it to the php array_pop()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as mentioned by @bert-w with php the functions array_pop and array_shift returning null in the case of an empty array, when the $count parameter is 1 this implementation seems appropriate.

However, in the case that there is a user supplied parameter which is not 1 things get a little bit more difficult...
Considering the current behaviour of the function it may be better to apply something similar to the following logic

if ($count === 1) {
    return object | null;
}

if ($count < 0 || $this->count() === 0) {
    return empty collection;
}

return $count item collection;

The more I think about it, it is probally more appropriate to seperate the funtionality into classic pop functionality returning object | null, and popMultiple which takes a parameter and returns a collection. (As this is already in production it would be a breaking change?)

@devcircus
Copy link
Contributor

Current behavior seems reasonable. Either way, probably doesn't need to change before version 9.

@taylorotwell
Copy link
Member

I agree with the comments that determining when to return null or an empty collection needs some work.

* @return mixed
*/
public function pop($count = 1)
public function pop($count = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow! that was a fast review!!!!

* @return mixed
*/
public function shift($count = 1)
public function shift($count = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change.

@craig-sen
Copy link
Author

@taylorotwell @devcircus @morloderex @bert-w

Thanks for the feedback!

after thinking about it over the weekend, instead of having a special case for 1,returning the traditional item|null when a parameter was supplied and returning an (empty) collection in other situations made more sense to my way of thinking.

To make chaining simpler, I also decided to return an empty collection in the case the collection was empty or the parameter was less than 1 as popping from the start of the array seemed redundant (that's what shift is for). while I know that it is a breaking change, it makes things simpler than adding boolean logic into the mix.

Let me know what you think.

@taylorotwell
Copy link
Member

I'll fix this on my end.

@taylorotwell
Copy link
Member

bd89575

@craig-sen craig-sen deleted the prevent_null_being_added_to_pop_and_shift branch August 10, 2021 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants