[swift-evolution] sortBy, minElementBy and maxElementBy methods

Howard Lovatt howard.lovatt at gmail.com
Mon Jan 4 14:19:52 CST 2016


+1 for the reduce version that Andrew presented, it has wider applicability.


> On 4 Jan 2016, at 10:42 AM, Andrew Bennett via swift-evolution <swift-evolution at swift.org> wrote:
> 
> As an alternative to minElement and maxElement, this could reduce the number of overloads and provide autocomplete:
> 
> extension SequenceType {
>     @warn_unused_result
>     func reduce<C: Comparable>(
>         @noescape combine: (C, C) throws -> Bool,
>         @noescape by key: Generator.Element -> C
>     ) rethrows -> Generator.Element?
>     {
>         var generator = self.generate()
>         guard let first = generator.next() else {
>             return nil
>         }
>         var best = first, bestKey = key(first)
>         while let element = generator.next() {
>             let elementKey = key(element)
>             if try !combine(bestKey, elementKey) {
>                 bestKey = elementKey
>                 best = element
>             }
>         }
>         return best
>     }
> }
> 
> print(["a","ab","abc"].reduce(<, by: { $0.characters.count })) // Optional("a")
> print(["a","ab","abc"].reduce(>, by: { $0.characters.count })) // Optional("abc")
> 
> The regular minElement, maxElement methods could have this alternative when you don't want "by":
> 
> extension SequenceType {
>     @warn_unused_result
>     func reduce(
>         @noescape combine: (Generator.Element, Generator.Element) throws -> Bool
>     ) rethrows -> Generator.Element?
>     {
>         var generator = self.generate()
>         guard let first = generator.next() else {
>             return nil
>         }
>         var best = first
>         while let element = generator.next() {
>             best = try combine(best, element) ? best : element
>         }
>         return best
>     }
> }
> 
> print([0,1,2,3].reduce(<)) // Optional(0)
> print([0,1,2,3].reduce(>)) // Optional(3)
> 
> It may be more efficient to define this on CollectionType where SubSequence.Generator.Element == Generator.Element, using .first and .dropFirst() rather than .generate(), but it's less flexible and this was enough to illustrate the alternative.
> 
> 
> On Fri, Jan 1, 2016 at 7:20 AM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> > I don’t get the resistance to Dave’s solution? I think it works well and much more applicable.
> 
> I have two issues:
> 
> 1. It's less discoverable. Someone merely *typing* `sort` into their editor will see `sortBy` right below it in their autocompletion list, and might discover it that way.
> 
> 2. It forces a naïve implementation, which may not be the best idea. In the Perl world, for instance, we would usually use a Schwartzian transform to implement this, particularly if the key might be expensive to compute:
> 
>         array.map { ($0, sortKey($0)) }.sort { $0.1 < $1.1 }.map { $0.0 }
> 
> Having said that, I think both of these concerns are relatively  minor.
> 
> --
> Brent Royal-Gordon
> Architechies
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
>  _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160105/8f907e32/attachment.html>


More information about the swift-evolution mailing list