[8.x] Add reduceMany to Collections
#39078
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Sometimes you need to compute multiple aggregate values from a collection. In many cases, it's fine to perform separate operations, but in cases where these values are interdependent, or there's a material performance cost to iterating the collection multiple times, this is not ideal.
This PR introduces a
reduceManyoperation that behaves exactly likereducebut allows for carrying as many values as needed. Rather than using the simplest example (see the added tests for this case), here's a slightly more complicated "real-world" example:(See this Twitter thread for another real-world use-case).
In the end, the API is exactly the same as
reduceexcept that you can pass in more$initialvalues and receive a corresponding number of$carryvalues before the$valueand$key. The only other difference is that you must return an array in your reducer that corresponds to the number of values you're reducing.I've intentionally left this method off the
Enumerableinterface for backwards-compatibility reasons. If this PR gets merged, I would suggest adding it to the interface in9.xand possibly updating the signature ofreduceto behave the same way (which would be backwards compatible but change the interface and thus affect anyone who has a custom implementation).