How to sort objects by its enum value?

Implement the Comparable protocol on your enum. It gives you a static func < (lhs: Difficulty, rhs: Difficulty) -> Bool method where you define the sort.

Here is a full sample using a property to simplify the ordering

enum Difficulty: String, Comparable {
    case easy = "easy"
    case moderate = "moderate"
    case hard(String) = "hard"

    private var sortOrder: Int {
        switch self {
            case .easy:
                return 0
            case .moderate:
                return 1
            case .hard(_):
                return 2
        }
    }

     static func ==(lhs: Difficulty, rhs: Difficulty) -> Bool {
        return lhs.sortOrder == rhs.sortOrder
    }

    static func <(lhs: Difficulty, rhs: Difficulty) -> Bool {
       return lhs.sortOrder < rhs.sortOrder
    }
}

Making it possible to use

data.sort { $0.workout.difficulty! < $1.workout.difficulty! }

edit/update: Swift 5.1 or later

You can change your enumeration RawValue type to integer and use its rawValue to sort your Workouts. Btw you should use a structure instead of a class and similar to what was suggested by Igor you could make your struct comparable instead of the enumeration:

struct Workout {
    let name: String
    let difficulty: Difficulty
}

extension Workout {
    enum Difficulty: Int { case easy, moderate, hard }
}


extension Workout: Comparable {
    static func <(lhs: Workout, rhs: Workout) -> Bool { lhs.difficulty.rawValue < rhs.difficulty.rawValue }
}

let wk1 = Workout(name: "night", difficulty: .hard)
let wk2 = Workout(name: "morning", difficulty: .easy)
let wk3 = Workout(name: "afternoon", difficulty: .moderate)

let workouts = [wk1, wk2, wk3]  // [{name "night", hard}, {name "morning", easy}, {name "afternoon", moderate}]

let sorted = workouts.sorted()  // [{name "morning", easy}, {name "afternoon", moderate}, {name "night", hard}]

Tags:

Swift