私はAnyObject
で構成されている配列を持っています。それを反復処理して、配列インスタンスであるすべての要素を見つけます。
Swiftでオブジェクトが特定のタイプであるかどうかを確認する方法はありますか。
特定の種類に対して確認したい場合は、次のようにします。
if let stringArray = obj as? [String] {
// obj is a string array. Do something with stringArray
}
else {
// obj is not a string array
}
あなたは「as!」を使うことができます。 obj
が[String]
型ではない場合、ランタイムエラーが発生します。
let stringArray = obj as! [String]
一度に1つの要素をチェックすることもできます。
let items : [Any] = ["Hello", "World"]
for obj in items {
if let str = obj as? String {
// obj is a String. Do something with str
}
else {
// obj is not a String
}
}
Swift 2.2 - 4.0.3 でできること:
if object is String
{
}
それから配列をフィルタリングします。
let filteredArray = originalArray.filter({ $0 is Array })
もしオブジェクト が 与えられた型のサブタイプであるかどうかだけ知りたいのなら、もっと簡単なアプローチがあります:
class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}
func area (shape: Shape) -> Double {
if shape is Circle { ... }
else if shape is Rectangle { ... }
}
インスタンスが特定のサブクラス型であるかどうかを確認するには、型チェック演算子(is)を使用します。型チェック演算子は、インスタンスがそのサブクラス型である場合はtrueを返し、そうでない場合はfalseを返します。」抜粋:Apple Inc.「The Swift Programming Language」 iBooks 。
上記では、「特定のサブクラス型の」という句が重要です。 is Circle
およびis Rectangle
の使用は、その値shape
がShape
(Circle
およびRectangle
のスーパークラス)として宣言されているため、コンパイラーによって受け入れられます。
プリミティブ型を使用している場合、スーパークラスはAny
になります。これが一例です。
21> func test (obj:Any) -> String {
22. if obj is Int { return "Int" }
23. else if obj is String { return "String" }
24. else { return "Any" }
25. }
...
30> test (1)
$R16: String = "Int"
31> test ("abc")
$R17: String = "String"
32> test (nil)
$R18: String = "Any"
それには2つの方法があります。
if let thisShape = aShape as? Square
または
aShape.isKindOfClass(Square)
これが詳細な例です。
class Shape { }
class Square: Shape { }
class Circle: Shape { }
var aShape = Shape()
aShape = Square()
if let thisShape = aShape as? Square {
println("Its a square")
} else {
println("Its not a square")
}
if aShape.isKindOfClass(Square) {
println("Its a square")
} else {
println("Its not a square")
}
編集:3今:
let myShape = Shape()
if myShape is Shape {
print("yes it is")
}
Swift4の場合:
if obj is MyClass{
// then object type is MyClass Type
}
drawTriangle がUIViewのインスタンスであると想定します。drawTriangleがUITableView型であるかどうかを確認します。
In Swift 3 、
if drawTriangle is UITableView{
// in deed drawTriangle is UIView
// do something here...
} else{
// do something here...
}
これは自分で定義したクラスにも使用できます。これを使用してビューのサブビューを確認できます。
このタスク専用に構築された組み込み機能を使用しないのはなぜですか。
let myArray: [Any] = ["easy", "as", "that"]
let type = type(of: myArray)
Result: "Array<Any>"
これについて警告してください。
var string = "Hello" as NSString
var obj1:AnyObject = string
var obj2:NSObject = string
print(obj1 is NSString)
print(obj2 is NSString)
print(obj1 is String)
print(obj2 is String)
最後の4行はすべてtrueを返します。これは、次のように入力した場合に起こります。
var r1:CGRect = CGRect()
print(r1 is String)
...それはもちろん "false"を出力しますが、警告はCGRectからStringへのキャストが失敗することを示します。そのため、いくつかの型はブリッジされ、 'is'キーワードは暗黙のキャストを呼び出します。
あなたはこれらのうちの一つを使うべきです:
myObject.isKind(of: MyClass.self))
myObject.isMember(of: MyClass.self))
未使用の定義値(let someVariable ...)のために警告を表示せずにクラスをチェックしたいだけの場合は、単にletのものをブール値に置き換えることができます。
if (yourObject as? ClassToCompareWith) != nil {
// do what you have to do
}
else {
// do something else
}
Xcodeは、私がlet方法を使用し、定義された値を使用しなかったときにこれを提案しました。
なぜこんな風に使わないの?
fileprivate enum types {
case typeString
case typeInt
case typeDouble
case typeUnknown
}
fileprivate func typeOfAny(variable: Any) -> types {
if variable is String {return types.typeString}
if variable is Int {return types.typeInt}
if variable is Double {return types.typeDouble}
return types.typeUnknown
}
swift 3では.
スイフト3:
class Shape {}
class Circle : Shape {}
class Rectangle : Shape {}
if aShape.isKind(of: Circle.self) {
}
nil
がmyObject
でない場合、myObject as? String
はString
を返します。それ以外の場合は、String?
を返すので、myObject!
を使用して文字列自体にアクセスするか、myObject! as String
を使用して安全にキャストできます。
受け入れられた答えと他のいくつかに基づく完全性のためだけに:
let items : [Any] = ["Hello", "World", 1]
for obj in items where obj is String {
// obj is a String. Do something with str
}
ただし、(compactMap
は、filter
がしない値を「マッピング」することもできます):
items.compactMap { $0 as? String }.forEach{ /* do something with $0 */ ) }
switch
を使用するバージョン:
for obj in items {
switch (obj) {
case is Int:
// it's an integer
case let stringObj as String:
// you can do something with stringObj which is a String
default:
print("\(type(of: obj))") // get the type
}
}
しかし、質問にこだわって、配列(つまり[String]
)かどうかを確認するには:
let items : [Any] = ["Hello", "World", 1, ["Hello", "World", "of", "Arrays"]]
for obj in items {
if let stringArray = obj as? [String] {
print("\(stringArray)")
}
}
またはより一般的には( この他の質問の答え を参照):
for obj in items {
if obj is [Any] {
print("is [Any]")
}
if obj is [AnyObject] {
print("is [AnyObject]")
}
if obj is NSArray {
print("is NSArray")
}
}
サーバーからの応答で辞書の配列または単一の辞書を受け取ることがわからない場合は、結果に配列が含まれているかどうかを確認する必要があります。
私の場合は、一回を除いて常に一連の辞書を受け取ります。そのため、Swift 3では以下のコードを使用しました。
if let str = strDict["item"] as? Array<Any>
これは?配列は取得した値が(辞書項目の)配列かどうかをチェックします。それ以外の場合は、配列内に保持されていない単一の辞書アイテムであるかどうかを処理できます。
Swift 4.2、私の場合はisKind関数を使う。
isKind(of :)レシーバが特定のクラスのインスタンスか、そのクラスから継承したクラスのインスタンスかを示すブール値を返します。
let items : [AnyObject] = ["A", "B" , ... ]
for obj in items {
if(obj.isKind(of: NSString.self)){
print("String")
}
}
続きを読む https://developer.Apple.com/documentation/objectivec/nsobjectprotocol/1418511-iskind
このような応答がある場合:
{
"registeration_method": "email",
"is_stucked": true,
"individual": {
"id": 24099,
"first_name": "ahmad",
"last_name": "zozoz",
"email": null,
"mobile_number": null,
"confirmed": false,
"avatar": "http://abc-abc-xyz.amazonaws.com/images/placeholder-profile.png",
"doctor_request_status": 0
},
"max_number_of_confirmation_trials": 4,
"max_number_of_invalid_confirmation_trials": 12
}
anyObjectとして読み込まれる値is_stucked
を確認したいのですが、これだけです。
if let isStucked = response["is_stucked"] as? Bool{
if isStucked{
print("is Stucked")
}
else{
print("Not Stucked")
}
}