lxcid / ListDiff

Swift port of IGListKit's IGListDiff

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Equatable intersects with other comparing parts in project

mojidabckuu opened this issue · comments

Diffable uses == operator to determine if two objects are same or not. If you are using ListDiff when some model stores visual information and in the same time is a part of another system which is basing on == operator it breaks the logic.
For example you have a Post and each post has a badge of views.

class Post: Diffable {
  var id: Int
  var badge: Int

 func ==(lhs: Post, rhs: Post) -> Bool { return lhs.id == rhs.id && lhs.badge == rhs.badge }
 var diffIdentifier: AnyHashable { return self.id }
}

The PK is id attribute. Badge is just a number to render and doesn't represent object itself. Let's assume you want to refresh your views since badge is not the same. Then badge becomes a part of ==. So if you are trying to lookup though the array of posts having id only then it requires write blocks like where: { $0.id == some_id } which is not correct and other libs based on == couldn't success to find an object, etc.

Expected behaviour is to have an independent operator/method to differentiate two objects for updates.

I think Diffable is mostly only providing an identity mechanism. The equality is handled by Equatable.

public static func diffing<T: Diffable & Equatable>(oldArray:Array<T>, newArray:Array<T>) -> Result {

The part where equatable come into play is in these lines where we detect if the the 2 identical element are not equal.

if oldIndex < oldArray.count {
let n = newArray[i]
let o = oldArray[oldIndex]
if n != o {
entry.updated = true
}
}

I think semantically wise, this is correct. If something is not equal, ListDiff will let you know about it.

In your case, you might want a ViewModel representation so that you does not need to populate your model with view related attributes.

struct PostViewModel: Diffablel {
  post: Post
  badge: Int

  var diffIdentifier: Int {
    return self.post.id;
  }
}

Pardon me if there's syntax error, I'm kinda rusty with Swift nowadays.

That's correct. I propose to add an extra operator to compare 2 elements in terms of diffing.