簡體   English   中英

檢查 json 響應是數組還是整數或字符串作為鍵?

[英]check the json response is array or int or string for a key?

我有 json 響應,其中“產品”鍵有時具有 int 值,在某些情況下它有一個數組? 如何檢查它是否具有數組或 Int?

"products": 25

或者

"products": [77,80,81,86]

我正在使用這個

self.productsCount = mResp["products"] as! [Int]

但是每次沒有數組時它都會崩潰。

現在我不知道如何檢查這個,因為我有不同的 Int 和 Array 選項?

請幫助我。謝謝

它崩潰是因為你強制解包為一個整數數組,即使你只有一個整數。 解決方案是檢查兩者:

self.productsCount = mResp["products"] as? [Int] ?? mResp["products"] as? Int

其他解決方案

if let proCount = mResp["products"] as? [Int] { 
  self.productsCount = proCount
} else {
  self.productsCount = mResp["products"] as? Int
}

這里沒有必要回退到Any 甚至像這樣有問題的 JSON 也可以使用Codable處理。 您只需要繼續嘗試不同的類型,直到其中一種有效。

struct Thing: Decodable {
    let products: [Int]

    enum CodingKeys: String, CodingKey {
        case products
    }

    init(from decoder: Decoder) throws {
        // First pull out the "products" key
        let container = try decoder.container(keyedBy: CodingKeys.self)

        do {
            // Then try to decode the value as an array
            products = try container.decode([Int].self, forKey: .products)
        } catch {
            // If that didn't work, try to decode it as a single value
            products = [try container.decode(Int.self, forKey: .products)]
        }
    }
}


let singleJSON = Data("""
{ "products": 25 }
""".utf8)

let listJSON = Data("""
{ "products": [77,80,81,86] }
""".utf8)

let decoder = JSONDecoder()

try! decoder.decode(Thing.self, from: singleJSON).products   // [25]
try! decoder.decode(Thing.self, from: listJSON).products     // [77, 80, 81, 86]

這是您想要的臨時解決方案。 使用“任何”類型檢查可能的類型。

    var anyType : Any!
    anyType = "123"
    anyType = ["Test","Test1"]
    anyType = 1
    if anyType is Array {
        print("is Array")
    }else if anyType is String {
        print("is String")
    }else if anyType is Int {
        print("is Int")
    }

假設您的 json 名稱是jsonData

檢查IntArray Int

if let intVal = jsonData["products"] as? Int {
    print("Products is a Integer: ", intVal)

} else if let jsonArr = jsonData["products"] as? [Int] {

    var intVals = [Int]()
    for json in jsonArr {
        intVals.append(json)
    }
    print("Json is array of Int: ", intVals)
}
let dict = [77,80,81,86]//Pass your parameter or parsed json value
 if dict is Array<Any> {
    print("Yes, it's an Array")
}
else{
      print("NO, it's not an Array")

}

通用解決方案是這樣的,

let products = mResp["products"] as? Any
if let item = products as? [Int] {
    print("array", item)
} else if let item = products as? Int {
    print("Integer", item)
}

使用Generics以獲得更好的解決方案並在解碼此模型時提供類型。

struct Product<T: Codable>: Codable {
    let products: T?
}

您可以將它與嵌套的try catch一起使用:

do {
    let product = try JSONDecoder().decode(Product<Int>.self, from: data)
    print(product)
} catch {
    do {
        let product = try JSONDecoder().decode(Product<[Int]>.self, from: data)
        print(product)
    } catch {
        print(error)
    }
}

注意:此解決方案假定可編碼結構中不超過幾個不同的類型變化屬性。 如果有多個類型不同的屬性,我建議使用接受的答案中提供的自定義init(decoder:) ,這將是更好的設計,而不是使用try-catch樹。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM