Ramsel Ramsel - 7 months ago 18
Swift Question

Comparing array of force unwrapped optionals

I'm writing a test:

func test_arrayFromShufflingArray() {

var videos = [MockObjects.mockVMVideo_1(), MockObjects.mockVMVideo_2(), MockObjects.mockVMVideo_3()]
let tuple = ShuffleHelper.arrayFromShufflingArray(videos, currentIndex:1)

var shuffledVideos = tuple.0
let shuffleIndexMap = tuple.1


// -- test order is different
XCTAssert(videos != shuffledVideos, "test_arrayFromShufflingArray fail")
}


But on the last line I get the last line:

Binary operator '!=' cannot be applied to two '[VMVideo!]' operands

Answer

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

But neither ImplicitlyUnwrappedOptional<Wrapped> nor Optional<Wrapped> conform to Equatable, even if the underlying type Wrapped does.

Possible options are (assuming that VMVideo conforms to Equatable):

  • Change your code so that videos and shuffledVideos are [VMVideo] arrays instead of [VMVideo!].

  • Compare the arrays elementwise:

    XCTAssert(videos.count == shuffledVideos.count
        && !zip(videos, shuffledVideos).contains {$0 != $1 })
    
  • Define a == operator for arrays of implicitly unwrapped equatable elements:

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