4 years ago there was a similar discussion:
Now 4 years passed and now we've got the new KeyPath feature, but we still don't have a convenient method to sort a sequence, or get the max / min element by its elements' properties
For example currently if we want to get the greatest element from a sequence according to a property of its elements, with the standard library the only way is to write a customized closure to compare 2 elements like this:
let max = sequence.max(by: { $0.property < $1.property })
Apart from inconvenience, there are 2 major issues with the API from my perspective:
-
The purpose of the closure's return value is not clear, which conflicts with Swift's fundamental API Design Guidelines. What does the Bool return value mean? If you can come up with the idea that it's sorting the array and it will return the last element of the array as the max value, then maybe you can somehow get the idea of "sorting the sequence, by returning
true
if $0's property is less than $1's property", but most people who tried their first time don't. -
Duplicates of information, which mis-typing could easily cause bugs. For example:
let max = sequence.max(by: { x, y in x.a < x.a })
let max = sequence.max(by: { x, y in x.a < y.b })
Both statements above are logically bugs, but they can't be checked at build time, which means it's not safe, and it conflicts with Swift's safety goal.
And since we already have keyPath feature in Swift, why couldn't we write statements like below?
let max = sequence.max(by: \.property)
This is much safer, much more clear, and much more developer-friendly comparing with existing methods.
Also, if we could have a method like
let max = sequence.max(by: { $0.getSomeValue(from: anotherData) })
then it could also be very convenient.