Misha Svyatoshenko Misha Svyatoshenko - 6 months ago 35
Swift Question

How can I extend Dictionary to work with Intervals

I want to extend Dictionary to support native Interval types such as HalfOpenInterval, ClosedInterval, so I can do something like this:

var dict = [
0.0..<1.0 : "Okay",
1.0..<2.0 : "Better",
2.0..<3.0 : "Perfect"]

for (range, value) in dict {
print("\(value) is assigned to \(range)")
}


The Dictionary key type must conform to Hashable protocol, and I'm thinking that I can make a hash value using composition of start and end properties if they also Hashable using code:

public var hashValue: Int {
let halfshift = sizeof(Int)*4
return start.hashValue ^ ((end.hashValue << halfshift) | (end.hashValue >> halfshift))
}


My best attempt to achieve this (full code):

extension IntervalType where Bound: Hashable {

public var hashValue: Int {
let halfshift = sizeof(Int)*4
return start.hashValue ^ ((end.hashValue << halfshift) | (end.hashValue >> halfshift))
}
}
extension HalfOpenInterval: Hashable where Bound: Hashable {}
extension ClosedInterval: Hashable where Bound: Hashable {}


is not working because of
error: extension of type 'HalfOpenInterval' with constraints cannot have an inheritance clause

Considering initial approach is not realizable in swift 2.2 What else I can try keeping it close to original use case?

Answer

Extend Range to make it Hashable:

extension Range: Hashable {
    public var hashValue: Int {
        get {
            return "\(self.startIndex)_\(self.endIndex)".hashValue
        }
    }
}

If you are running Swift 3 Alpha, replace startIndex and endIndex with lowerBound and upperBound.

(edited) In Swift 2 Range<Double> is not possible, but IntervalType can be extended same way

extension IntervalType {

    public var hashValue: Int {
        return "\(self)".hashValue
    }
}
extension HalfOpenInterval: Hashable {}
extension ClosedInterval: Hashable {}