web-dev-qa-db-ja.com

Swift 2配列にオブジェクトが含まれていますか?

なぜこれが機能しないのですか?文字列で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
10
Mitchell Hudson

DogEquatableを実装する必要があります。

class Dog: Equatable {

   var age = 1

}

func == (lhs: Dog, rhs: Dog) -> Bool {
      return lhs.age == rhs.age
}
13
jervine10

そこで何が起こっているのかを実際に説明するには、まず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を返すクロージャを使用して要素を検索します。

DogEquatableを採用していないため、最初の方法は使用できません。コンパイラは2番目の方法を使用しようとしますが、その方法にはパラメータとしてクロージャがあるため、エラーが表示されます。

解決策:EquatableDogを実装します。

オブジェクト参照の比較を探している場合は、単純なクロージャを使用できます。

let result = dogs.contains({ $0 === sparky })
10
Sulthan

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")

}
2
Anit Kumar

この回答は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」を愚かに指定しなかったため署名!

0
RenniePet