Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 2 Array Contains object?

Why isn't this working? I can use array.contains() on a String but it doesn't work for an Object.

var array = ["A", "B", "C"]

array.contains("A") // True

class Dog {
    var age = 1
}

var dogs = [Dog(), Dog(), Dog()]
var sparky = Dog()
dogs.contains(sparky) // Error Cannot convert value of type 'Dog' to expected argument type '@noescape (Dog) throws -> Bool
like image 523
Mitchell Hudson Avatar asked Feb 16 '16 21:02

Mitchell Hudson


1 Answers

To really explain what's happening there, first we have to understand there are two contains methods on Array (or better said, on SequenceType).

func contains(_ element: Self.Generator.Element) -> Bool

with constraints

Generator.Element : Equatable

and

func contains(@noescape _ predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Bool

The first one basically searches for a given element in the array using ==. The second one uses a closure that returns a Bool to search for elements.

The first method cannot be used because Dog doesn't adopt Equatable. The compiler tries to use the second method but that one has a closure as the parameter, hence the error you are seeing.

Solution: implement Equatable for Dog.

If you are looking for object reference comparison, you can use a simple closure:

let result = dogs.contains({ $0 === sparky })
like image 100
Sulthan Avatar answered Oct 14 '22 23:10

Sulthan