なぜこれが機能しないのですか?文字列でarray.contains()を使用できますが、オブジェクトでは機能しません。
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
Dog
はEquatable
を実装する必要があります。
class Dog: Equatable {
var age = 1
}
func == (lhs: Dog, rhs: Dog) -> Bool {
return lhs.age == rhs.age
}
そこで何が起こっているのかを実際に説明するには、まずcontains
に2つのArray
メソッドがあることを理解する必要があります(言い換えると、 SequenceType )。
func contains(_ element: Self.Generator.Element) -> Bool
制約付き
Generator.Element : Equatable
そして
func contains(@noescape _ predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Bool
最初のものは基本的に==
を使用して配列内の特定の要素を検索します。 2つ目は、Bool
を返すクロージャを使用して要素を検索します。
Dog
はEquatable
を採用していないため、最初の方法は使用できません。コンパイラは2番目の方法を使用しようとしますが、その方法にはパラメータとしてクロージャがあるため、エラーが表示されます。
解決策:Equatable
にDog
を実装します。
オブジェクト参照の比較を探している場合は、単純なクロージャを使用できます。
let result = dogs.contains({ $0 === sparky })
Swift
オブジェクトを使用していない場合は、このコードをcontainsに使用できます。
let elements = [ 10, 20, 30, 40, 50]
if elements.contains(50) {
print("true")
}
SwiftでNSObjectクラスを使用している場合。この変数は私の要件によるものです。要件に合わせて変更できます。
var cliectScreenList = [ATModelLeadInfo]()
var cliectScreenSelectedObject: ATModelLeadInfo!
これは同じデータ型用です。
{ $0.user_id == cliectScreenSelectedObject.user_id }
AnyObjectタイプにしたい場合。
{ "\($0.user_id)" == "\(cliectScreenSelectedObject.user_id)" }
完全な状態
if cliectScreenSelected.contains( { $0.user_id == cliectScreenSelectedObject.user_id } ) == false {
cliectScreenSelected.append(cliectScreenSelectedObject)
print("Object Added")
} else {
print("Object already exists")
}
この回答はOPの質問には関係ありませんが、Swiftエラーメッセージに直面している他の人には役立つかもしれません
タイプ '(whatever)'の引数リストで 'contains'を呼び出すことはできません
しかし、最初の簡単なクイズ:ここで問題を見つけることができますか?
internal class FrameworkAdminConnections {
private var _localConnectionKeys = [Int]()
... other code omitted
public func isLocalConnection(_ connectionKey : Int) {
return _localConnectionKeys.contains(connectionKey)
}
}
Swiftは、タイプ(Int)の引数リストでcontains()を呼び出すことができないと言い続けましたが、これは非常に役に立たないエラーメッセージであり、最終的にそれを理解するのにどれくらいの時間がかかったかをあえて認めません。
本当の問題は、Swiftの推論エンジンがcontains()メソッドの結果がどうあるべきかを理解できなかったことです-isLocalConnection()メソッドで「-> Bool」を愚かに指定しなかったため署名!