Sorting by accessor/closure

I expected (spoiled by countless different languages) Swift had something like the following:

extension Collection {
    func sorted<Key: Comparable>(on accessor: ((Self.Element) -> Key), order: SortOrder = .forward)
        -> [Self.Element]
    {
        self.sorted(by: { (e1, e2) in
            order == .forward
                ? accessor(e1) < accessor(e2)
                : accessor(e1) > accessor(e2)
        })
    }
}

Example usage:

let files = try FileManager.default.contentsOfDirectory(
    at: dir, includingPropertiesForKeys: nil)

for f in files.sorted(on: \.absoluteString) {
    // do something
}

Have I missed something? Would this be a worthy addition?

EDIT: probably better to move the comparison out of the loop.

extension Collection {
    func sorted<Key: Comparable>(on accessor: ((Self.Element) -> Key), order: SortOrder = .forward)
        -> [Self.Element]
    {
        order == .forward
            ? self.sorted(by: { (e1, e2) in accessor(e1) < accessor(e2) })
            : self.sorted(by: { (e1, e2) in accessor(e1) > accessor(e2) })
    }
}
1 Like

This works:

for f in files.sorted(using: KeyPathComparator(\.absoluteString)) {
    print(f)
}
3 Likes