Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between elementsEqual and '==' in Swift?

I'm going through the Swift Standard Library, and I came across the method elementsEqual for comparing sequences.

I'm not really seeing the value of this function because it will only return true if the order is exactly the same. I figured this would have some use if it could tell me if two sequences contained the same elements, they just happen to be in a different order, as that would save me the trouble of sorting both myself.

Which brings me to my question:

Is there any difference between using elementsEqual and '==' when comparing two sequences? Are there pros and cons for one vs the other?

I am in my playground, and have written the following test:

let values = [1,2,3,4,5,6,7,8,9,10] let otherValues = [1,2,3,4,5,6,7,8,9,10] values == otherValues values.elementsEqual(otherValues)

both of these checks result in true, so I am not able to discern a difference here.

like image 688
arc4randall Avatar asked Jun 24 '17 19:06

arc4randall


1 Answers

After playing with this for a while to find a practical example for the below original answer I found a much more simple difference: With elementsEqual you can compare collections of different types such as Array, RandomAccessSlice and Set, while with == you can't do that:

let array = [1, 2, 3]
let slice = 1...3
let set: Set<Int> = [1, 2, 3] // remember that Sets are not ordered

array.elementsEqual(slice) // true
array.elementsEqual(set) // false
array == slice // ERROR
array == set // ERROR

As to what exactly is different, @Hamish provided links to the implementation in the comments below, which I will share for better visibility:

  • elementsEqual
  • ==

My original answer:

Here's a sample playground for you, that illustrates that there is a difference:

import Foundation

struct TestObject: Equatable {
    let id: Int
    static func ==(lhs: TestObject, rhs: TestObject) -> Bool {
        return false
    }
}

// TestObjects are never equal - even with the same ID
let test1 = TestObject(id: 1)
let test2 = TestObject(id: 1)
test1 == test2 // returns false

var testArray = [test1, test2]
var copiedTestArray = testArray

testArray == copiedTestArray // returns true
testArray.elementsEqual(copiedTestArray) // returns false

Maybe someone knows for sure, but my guess is that == computes something like memoryLocationIsEqual || elementsEqual (which stops evaluating after the memory location is indeed equal) and elementsEqual skips the memory location part, which makes == faster, but elementsEqual more reliable.

like image 126
Benno Kress Avatar answered Nov 14 '22 23:11

Benno Kress