-
-
Notifications
You must be signed in to change notification settings - Fork 35
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
New Operations: Compare
, Max
, Min
#255
Conversation
$result = Collection::fromIterable([1, 4, 3, 0, 2]) | ||
->min() // [4 => 0] | ||
->current(); // 0 |
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.
I didn't want to do it in this PR because I wanted it to be simple and just rely on foldLeft1
, but I think we should make a dedicated PR before the next major release to change the behaviour of all reduction operations like reduce
, foldLeft
, foldRight
etc.
While in some cases it might be useful to have these operations return a collection, it's much more common for users to expect these to return a single value; after all, that's the typical behaviour of reductions. This is the case in other languages (just a couple examples):
This change would make Collection easier to use and also make it easier to differentiate between some operations, like Reduce (will return a single value) and Reduction (will continue to return a collection).
WDYT @drupol?
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.
I think we should do that before the next major release indeed.
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.
I would like to work on this, we should gather our idea for next major versions, can't wait for it :=)
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.
yep! I'll create an issue and we can list out the methods we think need this treatment
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.
I have another idea for this which would require a bit of rewriting if you're ok with this.
How about changing the behavior of the optional callback
that we can pass to min()
or max()
?
The callback would return an numeric value only and then, we compare for min
and max
internally in the operation, so we don't let the user alter the behavior of these operation through a callback.
Example:
$callback = static fn (object $o): int => $o->age;
$result = Collection::fromIterable([(object) ['id' => 2, 'age' => 5], (object) ['id' => 1, 'age' => 10]])
->min($callback)
->current(); // (object) ['id' => 2, 'age' => 5]
WDYT ?
Hey @drupol, thanks for looking at this. I like the intent of restricting a bit the callback that can be passed to these operations. However, returning a single value from the callback you propose would not be sufficient because of two reasons I think:
Because of this, I might want to do: $maxCallback = static fn (stdClass $left, stdClass $right): stdClass => $left->age > $right->age && $left->height > $right->height
? $left
: $right
;
I think the restriction at the type level should be sufficient, and further than that it can be the responsibility of the user to ensure the correct element is returned from the callback based on their desired effect. I'm open to other suggestions though! |
Ok I understand and it's fine for me. However, I think we can already achieve this using a combination of the |
Sure, I think that would work. But are you saying that these operations should be based on those ones instead of the fold, or that there isn't a need for |
Hi Alex,
FYI, the implementation of the Maybe this is something within this PR, adding a WDYT ? |
Hey @drupol, Thanks for the clarifications. It's not entirely clear to me how $col = Collection::fromIterable([1, 2, 3]);
$callback = static fn ($left, $right) => $left > $right ? $right : $left;
$result = $col->compare($callback)->current(); // 3
$max = $col->max(); // internally uses `compare` + "max callback" -> 3
$min = $col->min(); // internally uses `compare` + "min callback" -> 1 If this is what you were thinking, should |
No worries for the For the rest, yes that's precisely that. WDYT about the idea? Would you be ok with that? We could then even think to do that:
|
Yes, that looks good. I'll work to implement those in this PR once I get the chance. |
I think I didn't look at this properly the first time - it seems that in this scenario these operations are doing a hidden "map" and changing the collection from a list of I'll implement a simpler version like the one proposed here. |
That's precisely that! What is wrong with that?
As you wish :) |
I think it makes the API and the typing more complex...it extends the range of things these comparison operations do, whereas it would be nicer to have a separation of responsibilities. I wouldn't expect a comparison operation to also change the type. In any case the additions would be backwards compatible so we can always extend them if there's demand. |
It doesn't change it in the collection. It changes it locally so it can run the callback, but the original collection items stays unchanged. Don't forget that most of the operations are lazy, so, applying a |
+ simplify `max` & `min`
Max
+ Min
OperationsCompare
, Max
, Min
I know it doesn't change the original collection and that the operations are lazy, that's not the issue. My concern was that the added complexity is not worth it in this case. Each operation can have it's own role - in this case |
I fully agree ! |
This should be ready for review again, let me know if you're happy with this version! I think it's a nice addition for now, we can tweak things further later if needed :) |
This is indeed a very nice addition as usual :) I will carefully review this in the evening and let you know asap. Thanks !!! |
Nothing to add here ! all good :) Ready to merge ! |
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.
💯
Thank you! 😁 |
Let's create issues for the remaining tasks we discussed in here ! |
This PR: