in MobiusTest/Source/SimpleDiff.swift [55:95]
func diff(lhs: ArraySlice<Substring>, rhs: ArraySlice<Substring>) -> [Difference] {
var lhsIndexMap = [String: [Int]]()
for (index, value) in zip(lhs.indices, lhs) {
lhsIndexMap[String(value), default: []].append(index)
}
var lhsSubStart = lhs.startIndex
var rhsSubStart = rhs.startIndex
var subLength = 0
var overlap = [Int: Int]()
for (indexRhs, value) in zip(rhs.indices, rhs) {
var innerOverlap = [Int: Int]()
for indexLhs in lhsIndexMap[String(value), default: []] {
let innerSubLength = (overlap[indexLhs - 1] ?? 0) + 1
innerOverlap[indexLhs] = innerSubLength
if innerSubLength > subLength {
subLength = innerSubLength
lhsSubStart = indexLhs - subLength + 1
rhsSubStart = indexRhs - subLength + 1
}
}
overlap = innerOverlap
}
var diffs = [Difference]()
if subLength == 0 {
if !lhs.isEmpty {
diffs.append(.delete(lhs))
}
if !rhs.isEmpty {
diffs.append(.insert(rhs))
}
} else {
diffs.append(contentsOf: diff(lhs: lhs.prefix(upTo: lhsSubStart), rhs: rhs.prefix(upTo: rhsSubStart)))
diffs.append(.same(rhs.suffix(from: rhsSubStart).prefix(subLength)))
diffs.append(contentsOf: diff(lhs: lhs.suffix(from: lhsSubStart + subLength), rhs: rhs.suffix(from: rhsSubStart + subLength)))
}
return diffs
}