Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Compare two sequences, report back the common elements, plus deletes/inserts required to make the sequences match
// See how to use it at the bottom of this file
// Helper struct for sequenceDiff
public struct SequenceDiff<T1, T2> {
public let common: [(T1, T2)]
public let removed: [T1]
public let inserted: [T2]
public init(common: [(T1, T2)] = [], removed: [T1] = [], inserted: [T2] = []) {
self.common = common
self.removed = removed
self.inserted = inserted
}
}
public func sequenceDiff<T1, T2>(_ first: [T1], _ second: [T2], with compare: (T1,T2) -> Bool) -> SequenceDiff<T1, T2> {
let combinations = first.flatMap { firstElement in (firstElement, second.first { secondElement in compare(firstElement, secondElement) }) }
let common = combinations.filter { $0.1 != nil }.flatMap { ($0.0, $0.1!) }
let removed = combinations.filter { $0.1 == nil }.flatMap { ($0.0) }
let inserted = second.filter { secondElement in !common.contains { compare($0.0, secondElement) } }
return SequenceDiff(common: common, removed: removed, inserted: inserted)
}
// How to use it:
let array1 = ["a", "b", "c"]
let array2 = ["b", "c", "d", "e"]
let diffs = sequenceDiff(array1, array2, with: ==)
print("common: \(diffs.common)")
print("removed: \(diffs.removed)")
print("inserted: \(diffs.inserted)")
// The output is
//
// common: [("b", "b"), ("c", "c")]
// removed: ["a"]
// inserted: ["d", "e"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment