Reputation: 7004
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
Upvotes: 3
Views: 439
Reputation: 7004
Martin R's answer was the better answer, but for this specific purpose I just converted to NSArray's and was able to use the ==
operator in Swift:
func test_arrayFromShufflingArray() {
let videos = [MockObjects.mockVMVideo_1(), MockObjects.mockVMVideo_2(), MockObjects.mockVMVideo_3()]
let videosNSArray: NSArray = videos.map { $0 }
let tuple = ShuffleHelper.arrayFromShufflingArray(videos, currentIndex:1)
let shuffledVideos = tuple.0
let shuffledVideosNSArray: NSArray = shuffledVideos.map { $0 }
// -- test order is different
XCTAssert(videosNSArray != shuffledVideosNSArray, "test_arrayFromShufflingArray fail")
// -- test elements are the same
let set = NSSet(array: videos)
let shuffledSet = NSSet(array: shuffledVideos)
XCTAssert(set == shuffledSet, "test_arrayFromShufflingArray fail")
}
Upvotes: 0
Reputation: 539795
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 }
}
Upvotes: 2
Reputation: 8718
Swift can't tell how to compare two arrays to see if their contents are identical unless it knows how to compare individual elements. So you need to implement the ==
function on your class and adopt Equatable
:
extension VMVideo: Equatable {
// nothing goes here, == function has to be at global scope
}
func ==(lhs: VMVideo, rhs: VMVideo) -> Bool {
// Up to you to determine what equality means for your object, e.g.:
return lhs.essentialProperty1 == rhs.essentialProperty1 &&
lhs.essentialProperty2 == rhs.essentialProperty2
}
EDIT To clarify how it interacts with NSObject
and to troubleshoot your environment, please confirm the following:
class UnderstandsEqual: NSObject {}
let ok1: [UnderstandsEqual] = [UnderstandsEqual(), UnderstandsEqual()]
let ok2: [UnderstandsEqual] = [UnderstandsEqual(), UnderstandsEqual()]
ok1 == ok2 // no problem, evaluates to true
class DoesntUnderstand {}
let bad1: [DoesntUnderstand] = [DoesntUnderstand(), DoesntUnderstand()]
let bad2: [DoesntUnderstand] = [DoesntUnderstand(), DoesntUnderstand()]
bad1 == bad2 // produces a compile-time error
Upvotes: 0