Skip to content

Instantly share code, notes, and snippets.

@KiGi
Forked from zats/CustomHashable.swift
Last active July 9, 2019 06:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KiGi/bf65bdadfae3fddce92cb9d5673fcc91 to your computer and use it in GitHub Desktop.
Save KiGi/bf65bdadfae3fddce92cb9d5673fcc91 to your computer and use it in GitHub Desktop.
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)
}
}
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