lxcid / ListDiff

Swift port of IGListKit's IGListDiff
MIT License
241 stars 23 forks source link

Equatable intersects with other comparing parts in project #4

Open mojidabckuu opened 6 years ago

mojidabckuu commented 6 years ago

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.

lxcid commented 6 years ago

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

https://github.com/lxcid/ListDiff/blob/7ab9495ca93b72db5cd264e37efaabdae9c39fa5/Sources/ListDiff.swift#L95

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

https://github.com/lxcid/ListDiff/blob/7ab9495ca93b72db5cd264e37efaabdae9c39fa5/Sources/ListDiff.swift#L147-L153

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.

mojidabckuu commented 6 years ago

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