Search code examples
swiftmultidimensional-arraytuplesequality

Cannot check equality for two-dim arrays of equatable tuples


I don't understand the following situation:

let a1: [[Double]] = [[1]]
let equ1 = a1 == a1 // This builds

let t1: (Double, Double) = (1, 1)
let equ2 = t1 == t1 // This builds also

let a2: [[(Double, Double)]]  = [[(1,1)]]
let equ3 = a2 == a2 // This gives a build error

The build error is

Binary operator '==' cannot be applied to two '[[(Double, Double)]]' operands  

Why can I check equality for a two-dim array of Double, for a tuple of 2 Doubles, but not for a two-dim array of this tuple?


Solution

  • It's expected behavior. Let's break down each case:

    1. Two-dimensional array
    let a1: [[Double]] = [[1]]
    let equ1 = a1 == a1
    

    You're comparing two-dimensional arrays of double, and since Double conformed to the Equatable protocol (== in this scenario), the array is fully conforming to the Equatable protocol too, which makes it able to compare. You may want to check this documentation.


    1. Tuple
    let t1: (Double, Double) = (1, 1)
    let equ2 = t1 == t1
    

    SE-0015, Swift 2.2.1 indicates that you're able to compare tuples up to 6 elements with the == function.

    let t1: (Double, Double, Double, Double, Double, Double, Double) = (1, 1, 1, 1, 1, 1, 1)
    let equ2 = t1 == t1 ❌
    
    //Binary operator '==' cannot be applied to two '(Double, Double, Double, Double, Double, Double, Double)' operands
    

    1. Two-dimensional array of tuple
    let a2: [[(Double, Double)]]  = [[(1,1)]]
    let equ3 = a2 == a2
    

    Tuples are not able to conform to any kind of protocol until now. Even each element inside is able to do so, but that doesn't mean the whole tuple can. I found this PR-46668 also asked the same question as you.


    Site note: You may want to wrap it up into a Struct or Class, something like:

    struct DoubleModel: Equatable {
        let firstElement: Double
        let secondElement: Double
    }
    
    let a3: [[DoubleModel]] = [[.init(firstElement: 1, secondElement: 1)]]
    let equ3 = a3 == a3 ✅