-
Notifications
You must be signed in to change notification settings - Fork 11.7k
[8.x] Add chunkWhile() collection method
#33980
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
Conversation
This is inspired by the similar method in [Ruby’s Enumerable](https://ruby-doc.org/core-2.7.1/Enumerable.html#method-i-chunk_while).
|
(updated the P.R description with code that actually makes sense 😅) |
chunkWhile() collection methodchunkWhile() collection method
|
Ping @JosephSilber |
|
I actually tried adding this functionality a while ago, but it didn't work out (the naming was quite confusing). I've been thinking of taking another shot at this, so thanks @redgluten for submitting this. Looks great 👍 Here are some thoughts:
In short, what I'm proposing is something like this (haven't tested it): public function chunkWhile(callable $callback)
{
return new static(function () use ($callback) {
$iterator = $this->getIterator();
$chunk = new Collection();
if ($iterator->valid()) {
$chunk[$iterator->key()] = $iterator->current();
$iterator->next();
}
while ($iterator->valid()) {
if (! $callback($iterator->current(), $iterator->key(), $chunk)) {
yield new static($chunk);
$chunk = new Collection();
}
$chunk[$iterator->key()] = $iterator->current();
$iterator->next();
}
if ($chunk->isNotEmpty()) {
yield new static($chunk);
}
});
}@redgluten if you want to submit a follow-up PR, go for it 👍 Otherwise I'll cook something up a little later, or tomorrow. |
|
Yeah, let's make the proposed changes. |
|
@JosephSilber Yeah I stumbled onto your PR while finishing up mine yesterday, seemed to me like this more general approach might be valuable. Very cool that we can defer to lazy collections. 🔥 Your proposed changes make total sense. The only concern I see is that using the chunk makes the common operation of comparing the current and previous elements a bit more wordy unless I’m missing some trick? It’s quite late on my side of the world to get a crack at it now feel free to make your changes if you have the time otherwise I’ll get back to it later on. 👍 |
|
@redgluten your original example would have to be converted to this: $chunks = collect(str_split('AABBCCCD'))
->chunkWhile(fn ($char, $key, $chars) => $chars->last() === $char));A tiny bit more verbose, but totally worth it for the additional flexibility. |
|
Oh yeah at that point the chunk’s last element is the previous 😅 that’s what you get from reading code before going to bed late at night I guess. 🙃 |
This is inspired by the similar method in Ruby’s Enumerable. It allows breaking up a collection into chunks based on evaluating a callback rather than just a given size.
An example application is for implementing Run-length encoding where you need to group together consecutive elements of equal nature:
I’ll gladly write a documentation PR as well if this gets merged.
Please be kind, this is my first code PR to Laravel 😍, I took the time to read the contribution guide and take inspiration from other tests while writing mine but I could have missed something. Collections is my favourite part of the framework, this was a very nice learning experience anyhow. 👍