Swift equality operator on nested arrays

Update: Conditional conformance has been implemented in Swift 4.1. In particular:

The standard library types Optional, Array, and Dictionary now conform to the Equatable protocol when their element types conform to Equatable. …

(from the Swift CHANGELOG).

Arbitrarily nested arrays of Equatable elements are Equatable now
and can be compared with ==. Your code

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y

compiles in Xcode 9.3 if Simple is Equatable.


(Old answer:)
The reason is similar as in Why is Equatable not defined for optional arrays. Arrays can be compared with == if the element type is Equatable:

/// Returns true if these arrays contain the same elements.
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool

That’s why

var a: [Simple] = [Simple(message: "a")]
var b: [Simple] = [Simple(message: "a")]
a == b // -> true

compiles.

But even for equatable types T, Array<T> does not conform to the Equatable protocol, compare Why can’t I make Array conform to Equatable?. Therefore, in

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]]
x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]’ operands

x and y are arrays with the element type [Simple] which does
not conform to the Equatable protocol, and there is no
matching == operator.

You could define a generic == operator for simply nested arrays as

func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool {
    return lhs.count == rhs.count && !zip(lhs, rhs).contains {$0 != $1 }
}

or more simply (as suggested by @kennytm):

func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool {
    return lhs.elementsEqual(rhs, by: ==)
}

This makes x == y compile and work as expected. At present, there seems
to be no way to define a == operator on arbitrarily nested arrays.

Leave a Comment