-
-
Save natecook1000/2665e7b845eef9fd3951a0b559069ee3 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
extension OrderedCollectionDifference { | |
public func inferringMoves<T: Hashable>(by f: (ChangeElement) -> T) -> OrderedCollectionDifference<ChangeElement> { | |
let removeDict: [T: Int?] = { | |
var res = [T: Int?](minimumCapacity: Swift.min(removals.count, insertions.count)) | |
for r in removals { | |
let key = f(r.element) | |
if res[key] != .none { | |
res[key] = .some(.none) | |
} else { | |
res[key] = .some(r.offset) | |
} | |
} | |
return res.filter { (_, v) -> Bool in v != .none } | |
}() | |
let insertDict: [T :Int?] = { | |
var res = [T :Int?](minimumCapacity: Swift.min(removals.count, insertions.count)) | |
for i in insertions { | |
let key = f(i.element) | |
if res[key] != .none { | |
res[key] = .some(.none) | |
} else { | |
res[key] = .some(i.offset) | |
} | |
} | |
return res.filter { (_, v) -> Bool in v != .none } | |
}() | |
return OrderedCollectionDifference.init(validatedChanges: map({ (c: OrderedCollectionDifference<ChangeElement>.Change) -> OrderedCollectionDifference<ChangeElement>.Change in | |
switch c { | |
case .remove(offset: let o, element: let e, associatedWith: _): | |
let key = f(e) | |
if removeDict[key] == nil { | |
return c | |
} | |
if let assoc = insertDict[key] { | |
return .remove(offset: o, element: e, associatedWith: assoc) | |
} | |
case .insert(offset: let o, element: let e, associatedWith: _): | |
let key = f(e) | |
if insertDict[key] == nil { | |
return c | |
} | |
if let assoc = removeDict[key] { | |
return .insert(offset: o, element: e, associatedWith: assoc) | |
} | |
} | |
return c | |
})) | |
} | |
} |
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
struct Person: Equatable { | |
var uuid: String | |
var name: String | |
var employer: String | |
} | |
let before = [ | |
Person(uuid: "4628c50f-4516-4d52-ad30-28ed81b3c1b3", | |
name: "Chris Lattner", | |
employer: "Apple"), | |
Person(uuid: "6a5ff808-91e0-4b1a-a4dc-37b30704c8a1", | |
name: "Mark Zuckerberg", | |
employer: "Facebook") | |
] | |
let after = [ | |
Person(uuid: "4628c50f-4516-4d52-ad30-28ed81b3c1b3", | |
name: "Chris Lattner", | |
employer: "Google"), | |
Person(uuid: "2e683426-801c-4754-924c-95920fc760a5", | |
name: "Bill Gates", | |
employer: "Microsoft") | |
] | |
let diff = before | |
.difference(from: after) | |
.inferringMoves(by: { $0.uuid }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment