[swift-evolution] sortBy, minElementBy and maxElementBy methods

Andrew Bennett cacoyi at gmail.com
Sun Jan 3 17:42:42 CST 2016


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> 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
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160104/6e7286dc/attachment.html>


More information about the swift-evolution mailing list