【问题标题】:update dictionary value in swift 3在 swift 3 中更新字典值
【发布时间】:2017-08-09 17:28:13
【问题描述】:
{
  "error": false,
  "error_msg": "Get trending data.",
  "Total_category": 2,
  "responseData": [
    {
      "categoryName": "Trending",
      "Trending": [
        {
          "category": "Trending",
          "trailerPrice": "",
          "isFavourit": null,
          "isWatchlist": null
        }
      ]
    },
    {
      "categoryName": "Comedy",
      "Comedy": [
        {
          "category": "Comedy",
          "trailerPrice": "",
          "isFavourit": null,
          "isWatchlist": null
        }
      ]
    }

  ]
}

我需要更新特定键 **("isFavourit")** 的内容,在 swift 3 中怎么可能?仅更新responseData-> index[1]->comedy[]-> "isFavourit" null to 1

我可以像这样设置字典的值 responseData[1][Comedy]![0]["isFavourit"] = 1 不能在 swift3 中工作。

如何设置“isFavourit”值为1?

我刚刚尝试了类似的东西

(arrVideoDetail[1]["comedy"] as! [Dictionary<String,Any>])[0]["isFavourit"] = 1

以上代码显示错误不能分配给'Any?'类型的不可变表达式?

【问题讨论】:

  • 请显示一些代码你试过什么?
  • 您是否尝试过搜索 Stack Overflow?您找不到任何有关管理此类 JSON 数据的信息吗?
  • 考虑将类别映射到自定义对象(结构或类)和名称isFavourit 意味着是Bool 而不是Int
  • 分享您的尝试和遇到的错误。
  • @user1000 请检查代码

标签: ios iphone swift dictionary swift3


【解决方案1】:

这真是糟糕的 JSON。问题是responseData 数组中的字典没有一致的键。第一个有键

  "categoryName": "Trending",
  "Trending": [

但第二个有钥匙

  "categoryName": "Comedy",
  "Comedy": [

这意味着在您提取categoryName 键的值之前,您不知道第二个键的名称。所以你必须停下来做这件事,然后才能继续。

因此,假设您将 JSON 保存在一个名为 json 的字符串中。那么:

    let d1 = try! JSONSerialization.jsonObject(with: json.data(using: .utf8)!)
    let a1 = (d1 as! [String:Any])["responseData"]
    let d2 = (a1 as! [[String:Any]])[1]
    let key = d2["categoryName"] as! String // "Comedy"
    let a2 = d2[key]!
    var d3 = (a2 as! [[String:Any]])[0]
    // ["isWatchlist": <null>, "trailerPrice": , "isFavourit": <null>, "category": Comedy]


现在d3 是您要查找的内部字典,您可以根据需要对其进行修改。


顺便说一句,你的 JSON 是一个很好的例子,说明为什么这一切在 Swift 4 中会变得更好。我们可以将整个 JSON 解析为自定义结构的属性:

struct MyJson : Decodable {
    let error : Bool
    let error_msg : String
    let Total_category : Int
    let responseData : [ResponseData]
    struct ResponseData : Codable {
        let categoryName : String
        let unknown : [Inner]
        struct Inner : Codable {
            let category : String
            let trailerPrice : String
            let isFavourit : String?
            let isWatchList : String?
        }
        private struct CK : CodingKey {
            var stringValue: String
            init?(stringValue: String) { self.stringValue = stringValue }
            var intValue: Int?
            init?(intValue: Int) { return nil }
        }
        init(from decoder: Decoder) throws {
            let con = try! decoder.container(keyedBy: CK.self)
            self.categoryName = try! con.decode(String.self, forKey:CK(stringValue:"categoryName")!)
            let key = self.categoryName
            self.unknown = try! con.decode([Inner].self, forKey: CK(stringValue:key)!)
        }
    }
}


配置我们的结构后,解析整个 JSON 只需一行代码!假设您的 JSON 在名为 json 的变量中:

let myjson = try JSONDecoder().decode(MyJson.self, from: json.data(using: .utf8)!)

您尝试访问的值可以非常简单地表达:

let fav = myjson.responseData[1].unknown[0].isFavourit

所以我要做的就是把我所有的let 变成var,现在它们都可以设置了,就像你想做的那样。

(有关此解决方案的更多信息,请参阅Swift 4 Decodable with keys not known until decoding time。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 2016-08-25
    • 2016-11-19
    • 1970-01-01
    • 2017-07-18
    • 2018-01-05
    • 1970-01-01
    相关资源
    最近更新 更多