Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Enum of custom types conform to hashable protocol

Tags:

swift

swift2

I have an enum like this:

enum Animals {
    case Cow     (MyCowClass)
    case Bird    (MyBirdClass)
    case Pig     (MyPigClass)
    case Chicken (MyChickenClass)
}

Each of the types conform to the hashable protocol. This enum then becomes a property of a different class:

class Farm {
    let name = "Bob's Farm"
    var animal = Animals

    required init(animal: Animals) {
        self.animal = animal
    }

I would like to get the hash value from the instance of the case and use that for the enum so I can make the Farm class hashable using the name & animal.

like image 245
Fred Faust Avatar asked Oct 29 '15 16:10

Fred Faust


2 Answers

You might make Animals hashable, e.g.:

enum Animals : Hashable {
    case Cow     (MyCowClass)
    case Bird    (MyBirdClass)
    case Pig     (MyPigClass)
    case Chicken (MyChickenClass)

    var hashValue: Int  {
        switch self {
        case .Cow(let v): return v.hashValue
        case .Bird(let v): return v.hashValue
        case .Pig(let v): return v.hashValue
        case .Chicken(let v): return v.hashValue
        }
    }
}
func ==(lhs: Animals, rhs: Animals) -> Bool {
    return ...
}

And likewise for class Farm, e.g.:

class Farm : Hashable  {

    var hashValue: Int {
        return [name.hashValue, animal.hashValue].hashValue
    }
}
func ==(lhs: Farm, rhs: Farm) -> Bool {
    return ...
}

And finally, a container of Ints implements a property hashValue

extension CollectionType where Generator.Element: Int {
    var hashValue: Int {
        return ...
    }
}

For appropriate algorithms, you may search the web - for example: http://www.eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx

like image 69
CouchDeveloper Avatar answered Oct 04 '22 06:10

CouchDeveloper


An alternative to the accepted answer, assuming you don't want your enum based on the associated object is the following:

private enum AnimalType: Int {
    case Cow = 0
    case Bird = 1
    case Pig = 2
    case Chicken = 3
}

func == (lhs: Animals, rhs: Animals) -> Bool {
    return lhs.hashValue == rhs.hashValue
}

enum Animals: Hashable {
    case Cow     (MyCowClass)
    case Bird    (MyBirdClass)
    case Pig     (MyPigClass)
    case Chicken (MyChickenClass)

    var hashValue: Int {
        get {
            switch self {
            case .Cow(_):
                return AnimalType.Cow.hashValue
            }
        }
    }
}
like image 29
Sandy Chapman Avatar answered Oct 04 '22 05:10

Sandy Chapman