Search code examples
swiftdatestructcomparable

Compare Day/Month in Swift Struct


I would like sort an array of SpecialDay instances: [struct1, struct2, struct3, ...] using the code below:

struct SpecialDay: Hashable, Comparable {
    var day: Int
    var month: Int

    var hashValue: Int {
        return (31 &* day.hashValue &+ month.hashValue)
    }
}

func ==(lhs: SpecialDay, rhs: SpecialDay) -> Bool {
    return lhs.day == rhs.day && lhs.month == rhs.month
}

func <(lhs: SpecialDay, rhs: SpecialDay) -> Bool {
    return lhs.day < rhs.day && lhs.month <= rhs.month
}

Sorting would be done like this:

let newArray = currentArray.sorted({ $0 < $1 })

I think I only need to find the right logic behind the comparable method:

func <(lhs: SpecialDay, rhs: SpecialDay) -> Bool

... but I am pulling my teeth on this one. My currently implemented logic is obviously not sorting correctly.

Any hints would be greatly appreciated.


Solution

  • The problem is the and in this line:

    return lhs.day < rhs.day && lhs.month <= rhs.month
    

    If the lhs month is less than the rhs it should always return true not taking into account the day. However, when you and with the comparison to days, you can get a false for the days not being less and a true for the months, which results in a false. You need something just a little more complicated:

    func <(lhs: SpecialDay, rhs: SpecialDay) -> Bool {
        if lhs.month < rhs.month { return true }
        else if lhs.month > rhs.month { return false }
        else {
            return lhs.day < rhs.day
        }
    }