-
-
Save KiGi/bf65bdadfae3fddce92cb9d5673fcc91 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public struct CustomHashable<T>: Hashable { | |
public let value: T | |
public typealias HashCalculator = (CustomHashable<T>, inout Hasher) -> Void | |
public typealias EqualityCalculator = (CustomHashable<T>, CustomHashable<T>) -> Bool | |
public typealias CacheTransformedData = (T) -> Any? | |
private let hashCalculator: HashCalculator | |
private let equalityCalculator: EqualityCalculator | |
let cacheTransformedData : Any? | |
public init(value: T, hashCalculator: @escaping HashCalculator, equalityCalculator: @escaping EqualityCalculator, dataCacheBuilder : @escaping CacheTransformedData ) { | |
self.value = value | |
self.hashCalculator = hashCalculator | |
self.equalityCalculator = equalityCalculator | |
self.cacheTransformedData = dataCacheBuilder(value) | |
} | |
public static func == (lhs: CustomHashable<T>, rhs: CustomHashable<T>) -> Bool { | |
return lhs.equalityCalculator(lhs, rhs) | |
} | |
public func hash(into hasher: inout Hasher) { | |
hashCalculator(self, &hasher) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private func pointHashCalculator(pointC: CustomHashable<CGPoint>, hasher: inout Hasher) { | |
let myInts : [Int] | |
if let cacheInts = pointC.cacheTransformedData as? [Int] { | |
myInts = cacheInts | |
} else { | |
myInts = [Int(pointC.value.x),Int(pointC.value.y)] | |
} | |
_ = myInts.map() {hasher.combine($0)} | |
} | |
private func pointEqualityCalculator(p1c: CustomHashable<CGPoint>, p2c: CustomHashable<CGPoint> ) -> Bool { | |
if let c1 = p1c.cacheTransformedData as? [Int], let c2 = p2c.cacheTransformedData as? [Int] { | |
return c1 == c2 | |
} else { | |
return Int(p1c.value.x) == Int(p2c.value.x) && Int(p1c.value.y) == Int(p2c.value.y) | |
} | |
} | |
private func pointCacheBuilder(p : CGPoint) -> Any? { | |
return [Int(p.x), Int(p.y)] | |
} | |
func hashTheUnhashable( allPoints : [CGPoint]) -> Set<CustomHashable<CGPoint>> { | |
var points: Set<CustomHashable<CGPoint>> = [] | |
for p in allPoints { | |
let hashablePoint = CustomHashable(value: p, hashCalculator: pointHashCalculator, equalityCalculator: pointEqualityCalculator, dataCacheBuilder: pointCacheBuilder) | |
points.insert(hashablePoint) | |
} | |
return points | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment