Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@blixt
Created August 8, 2015 01:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blixt/e461c0296e2b9162e2fd to your computer and use it in GitHub Desktop.
Save blixt/e461c0296e2b9162e2fd to your computer and use it in GitHub Desktop.
class ListDiff<T : Hashable> {
typealias IndexList = [Int]
typealias FromIndexToIndexList = [(from: Int, to: Int)]
// A list of indexes of where items were added.
let added: IndexList
// A list of indexes where items that have disappeared used to be.
let deleted: IndexList
// A list of tuples of indexes representing the old and new indexes of items that moved.
let moved: FromIndexToIndexList
init(before: [T], after: [T]) {
// Create a map with all the items in the smaller list mapped to indexes.
let beforeIsSmaller = before.count < after.count
var map = [T: Int]()
for (index, item) in enumerate(beforeIsSmaller ? before : after) {
map[item] = index
}
var added = IndexList()
var deleted = IndexList()
var moved = FromIndexToIndexList()
// Loop through the longer list to calculate all changed indexes.
for (index1, item) in enumerate(beforeIsSmaller ? after : before) {
if let index2 = map[item] {
if (index1 != index2) {
let (from, to) = beforeIsSmaller ? (index2, index1) : (index1, index2)
moved.append((from: from, to: to))
map.removeValueForKey(item)
}
} else {
if (beforeIsSmaller) {
added.append(index1)
} else {
deleted.append(index1)
}
}
}
// Handle any indexes still in the map.
for (_, index) in map {
if (beforeIsSmaller) {
deleted.append(index)
} else {
added.append(index)
}
}
self.added = added
self.deleted = deleted
self.moved = moved
}
}
let a = ["Anna", "Bob", "Cecilia", "Dennis", "Ellinor", "Frank"]
let b = ["Cecilia", "Bob", "Dennis", "Ellinor", "Gabriella", "Hubert"]
let myDiff = ListDiff<String>(before: a, after: b)
myDiff.added // [1, 5, 4]
myDiff.deleted // [0, 5]
myDiff.moved // [(from: 2, to: 0), (from: 3, to: 2), (from: 4, to: 3)]
@gwennguihal
Copy link

gwennguihal commented Sep 1, 2017

line 30 must be out the condition.
For testing, use:

let a = ["Roher","Anna", "Bob"]
let b = ["Roher","Cecilia","Anna", "Bob"]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment