Compare 2 arrays and list the differences - Swift

Xcode 11 has it supported (only available in iOS 13 or newer)

https://developer.apple.com/documentation/swift/array/3200716-difference

let oldNames = ["a", "b", "c", "d"]
    
let newNames = ["a", "b", "d", "e"]

let difference = newNames.difference(from: oldNames)

for change in difference {
  switch change {
  case let .remove(offset, oldElement, _):
    print("remove:", offset, oldElement)
  case let .insert(offset, newElement, _):
    print("insert:", offset, newElement)
  }
}

Output

remove: 2 c
insert: 3 e

Here's one implementation, but whether it is the one you are after is completely impossible to say, because you have not specified what you think the answer should be:

let answer = zip(array1, array2).map {$0.0 == $0.1}

That gives you a list of Bool values, true if the answer matches the right answer, false if it does not.

But let's say what you wanted was a list of the indexes of those answers that are correct. Then you could say:

let answer = zip(array1, array2).enumerated().filter() {
    $1.0 == $1.1
}.map{$0.0}

If you want a list of the indexes of those answers that are not correct, just change == to !=.


the easiest thing to do is use a Set. Sets have a symmetricDifference() method that does exactly this, so you just need to convert both arrays to a set, then convert the result back into an array.

Here’s an extension to make it easier:

extension Array where Element: Hashable {
    func difference(from other: [Element]) -> [Element] {
        let thisSet = Set(self)
        let otherSet = Set(other)
        return Array(thisSet.symmetricDifference(otherSet))
    } }

And here’s some example code you can use to try it out:

let names1 = ["student", "class", "teacher"]
let names2 = ["class", "teacher", "classroom"]
let difference = names1.difference(from: names2)

That will set difference to be ["student", "classroom"], because those are the two names that only appear once in either array.