Comparing optional arrays Comparing optional arrays swift swift

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 ([]).