DeepDiff icon indicating copy to clipboard operation
DeepDiff copied to clipboard

Replace DiffAware to Hashable

Open ton252 opened this issue 6 years ago • 3 comments

Could you explain why we need to use DiffAware protocol when Hashable do the same thing and there is a lot of helper functional out-of-the-box like Hasher etc.

For example, we have a simple struct:

struct SomeStruct<T: DiffAware, U: DiffAware> {
  var value: T
  var valuesArray: [U]
}

And if we want to conform DiffAware protocol, we need to calculate diffId something like this:

 var diffId: Int {
    let valueIds = self.values.map({ $0.diffId })
    
    var hasher = Hasher()
    hasher.combine(self.value.diffId)
    hasher.combine(valueIds)
    
    return hasher.finalize()
}

And if all the objects conformed Hashable protocol, I will not need to use map in this case and it will affect the performance.

As I remember map complexity is O(n).

ton252 avatar Mar 16 '19 07:03 ton252

@ton252 Hi, Hashable and Equatable are in fact useful, but I've seen it has caused some confusions, so I introduced DiffAware with diffId and compare function to make things more explicit. And diffId would ensure more id uniquing.

onmyway133 avatar Mar 18 '19 08:03 onmyway133

@ton252 To avoid having to repeatedly conform types to DiffAware, you can do this:

extension DiffAware where Self: Hashable {
    public var diffId: Int {
        return hashValue
    }

    public static func compareContent(_ a: Self, _ b: Self) -> Bool {
        return a == b
    }
}

extension UUID: DiffAware {}
extension CGFloat: DiffAware {}
// ...

This way, you can conform any type that is already Hashable to DiffAware without implementing diffId and compareContent each time. Saved me a couple lines.

dlindenkreuz avatar Apr 29 '19 18:04 dlindenkreuz

Can we improve API?

  1. in my case, I have "id" : "28722789326579082360373574526566400" it's a string and I can't really use it with diffId: Int. Plus I have
  2. I have
protocol BaseMessageViewModel: DiffAware  {

}
struct TextMessageViewModel: BaseMessageViewModel {
    
    public var diffId: Int {
        return hashValue
    }
   

I have a compile error Protocol 'BaseMessageViewModel' can only be used as a generic constraint because it has Self or associated type requirements

dbof10 avatar May 05 '19 14:05 dbof10