Skip to content

Adding Self-returning overload of sorted() for OrderedDictionary and OrderedSet? #477

@marcomasser

Description

@marcomasser

There are mutating methods on OrderedDictionary and OrderedSet that sort them in-place, so sorting is well-defined on these types. But there are no copy-returning sorted() variants for these types.

The question is: Is there a specific reason why these are not included so far? I realize that adding this would be a source-breaking change for OrderedSet, so I guess the bar for including this is very high by now.

FYI, I asked on the Swift Forums about this (but I was confused a bit and didn’t see the Sequence.sorted() version): https://forums.swift.org/t/why-is-there-a-sort-but-no-sorted-method-on-ordereddictionary-and-orderedset/79978/2


A little more info:

OrderedSet uses the default implementation from Sequence, which returns an Array instead of an OrderedSet, which is unfortunate if you want to keep working with an OrderedSet:

let set: OrderedSet = [3, 2, 1]
print(type(of: set.sorted())) // Array<Int>

let sortedSet = OrderedSet(set.sorted()) // Possible, but not ideal 😕

And OrderedDictionary sees the default implementation from Sequence, but the compiler rightly errors out:

let dict: OrderedDictionary = [1: "one", 2: "two", 3: "three"]
print(type(of: dict.sorted())) // error: Type 'OrderedDictionary<Int, String>.Element' (aka '(key: Int, value: String)') cannot conform to 'Comparable'

Adding Self-returning variants and thereby shadowing the Sequence implementations is very easy, of course, e.g.:

extension OrderedSet {
    func sorted() -> Self where Element: Comparable {
        var copy = self
        copy.sort()
        return copy
    }
}

extension OrderedDictionary {
    func sorted() -> Self where Key: Comparable {
        var copy = self
        copy.sort()
        return copy
    }
}

…which results in this:

let dict: OrderedDictionary = [1: "one", 2: "two", 3: "three"]
print(type(of: dict.sorted())) // OrderedDictionary<Int, String>

let set: OrderedSet = [3, 2, 1]
print(type(of: set.sorted())) // OrderedSet<Int>

…which is what I personally would have expected 🙂

Metadata

Metadata

Assignees

No one assigned

    Labels

    api-redesignSource breaking changes to consider when/if it ever becomes possible to do thatenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions