-
Notifications
You must be signed in to change notification settings - Fork 11k
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] Fix LazyCollection#unique() double enumeration #39041
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -773,28 +773,6 @@ public function reject($callback = true) | |
}); | ||
} | ||
|
||
/** | ||
* Return only unique items from the collection array. | ||
* | ||
* @param string|callable|null $key | ||
* @param bool $strict | ||
* @return static | ||
*/ | ||
public function unique($key = null, $strict = false) | ||
{ | ||
$callback = $this->valueRetriever($key); | ||
|
||
$exists = []; | ||
|
||
return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) { | ||
if (in_array($id = $callback($item, $key), $exists, $strict)) { | ||
return true; | ||
} | ||
|
||
$exists[] = $id; | ||
}); | ||
} | ||
|
||
Comment on lines
-776
to
-797
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would consider this a breaking change. Maybe you can only add the unique Method to the Lazy Collection and let the normal Collection stay the same with using the EnumeratesValues Trait. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The I'll let Taylor decide whether he considers this a breaking change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Laravel Nova global search is not working anymore because of this fix...
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @RomanNebesnuyGC is your comment intentionally in this thread, or you meant to comment generally on the PR? Can you paste the actual stack trace? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JosephSilber
it's FatalError So it's globally broken. Everywhere when you want to use Laravel: 8.63.0 (on 8.62.0 all is ok) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I created a sample repository (with a readme) showing that the @RomanNebesnuyGC Can you please create a PR to that repository that shows how it's broken? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JosephSilber sorry all is ok. It's my fault. All is working perfectly. |
||
/** | ||
* Return only unique items from the collection array using strict comparison. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to explain why this didn't work:
The call to
$this->reject
returned a newLazyCollection
instance. Every time the collection is enumerated, the callback (that was passed toreject
) gets called again, but it's reusing the same$exists
cache of found items, so anything that was previously enumerated is treated as a duplicate 😦The solution is to have a separate implementation of the
unique()
method for theLazyCollection
class. In that implementation, we can move the$exists
cache into theGenerator
function passed to the constructor, so that each enumeration has its own cache 👍