Comparing optional arrays
The reason it works for simpler types is because there is a version of ==
that is defined for optionals that contain types that are Equatable
:
func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool
But while Int
is Equatable
, Array
is not (because it might contain something that is not equatable - in which case how could it be). All Equatable
things have an ==
operator, but not all things with an ==
operator are Equatable
.
You could write a special-case version of ==
specifically for optional arrays containing equatable types:
func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool { switch (lhs,rhs) { case (.Some(let lhs), .Some(let rhs)): return lhs == rhs case (.None, .None): return true default: return false }}
You could also generalize this to cover any collection containing equatable elements:
func ==<C: CollectionType where C.Generator.Element: Equatable> (lhs: C?, rhs: C?) -> Bool { switch (lhs,rhs) { case (.Some(let lhs), .Some(let rhs)): return lhs == rhs case (.None, .None): return true default: return false }}
adding swift 3 version of Airspeed's answer:
func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool { switch (lhs,rhs) { case (.some(let lhs), .some(let rhs)): return lhs == rhs case (.none, .none): return true default: return false }}func ==<C: Collection where C.Iterator.Element: Equatable>(lhs: C?, rhs: C?) -> Bool { switch (lhs,rhs) { case (.some(let lhs), .some(let rhs)): return lhs == rhs case (.none, .none): return true default: return false }}
Swift 4.1
Update: The missing functionality has been implemented in Swift 4.1.
Your code
let a: [Int]? = [1,2]let b: [Int]? = [1,2]a == b
compiles and works as expected since Xcode 9.3 (Swift 4.1).
Old answer
The easiest is not to use optional array and use an empty array ([]
) instead of nil
- in case you don't need to distinguish between those two cases.
let a = [1,2]let b = [1,2]let c = []a == bb != c
It worked in my case when I was writing Equatable extension for a struct. Instead of using property categories: [Category]?
I have just changed it to categories: [Category]
and parsed missing categories as empty array ([]
).