如何在 Swift 中将键值对添加到类型为 [String:AnyObject] 的字典中?

Posted

技术标签:

【中文标题】如何在 Swift 中将键值对添加到类型为 [String:AnyObject] 的字典中?【英文标题】:How to add a key value pair to a dictionary of type [String:AnyObject] in Swift? 【发布时间】:2016-09-30 18:35:23 【问题描述】:

我已将 JSON 文件的内容存储在 [[String:AnyObject]] 类型的字典数组中。我想为 [String:AnyObject] 字典中的每个项目添加一个新的键值对。我不断收到错误消息:无法分配给“AnyObject?!”类型的不可变表达式 有没有办法解决这个问题?

主题声明如下:

    var subjects = [[String:AnyObject]]()

编辑:很抱歉没有发布代码。所以,这是 [[String:AnyObject]] 数组的元素之一

    "subjects" : 
        "humanities" : [
            "sno" : "TH5", "code" : 205, "name" : "Mathematics III", "credits" : 4
        ],
        "applied" : [
            "sno" : "TH3", "code" : 203, "name" : "Power Apparatus", "credits" : 4,
            "sno" : "TH4", "code" : 204, "name" : "Electrical Measurements", "credits" : 4
        ],
        "core" : [
            "sno" : "TH1", "code" : 201, "name" : "Electronics I", "credits" : 4,
            "sno" : "TH2", "code" : 202, "name" : "Circuits and Systems", "credits" : 4
        ],
        "theory" : [
            "sno" : "TH1", "code" : 201, "name" : "Electronics I", "credits" : 4, "category" : "C",
            "sno" : "TH2", "code" : 202, "name" : "Circuits and Systems", "credits" : 4, "category" : "C",
            "sno" : "TH3", "code" : 203, "name" : "Power Apparatus", "credits" : 4, "category" : "A",
            "sno" : "TH4", "code" : 204, "name" : "Electrical Measurements", "credits" : 4, "category" : "A",
            "sno" : "TH5", "code" : 205, "name" : "Mathematics III", "credits" : 4, "category" : "H"
        ],
        "practical" : [
            "sno" : "PR1", "code" : 206, "name" : "Electronics I", "credits" : 2,
            "sno" : "PR2", "code" : 207, "name" : "Power Apparatus", "credits" : 2,
            "sno" : "PR3", "code" : 208, "name" : "Electrical Measurements", "credits" : 2,
            "sno" : "PR4", "code" : 209, "name" : "Machine Drawing", "credits" : 3,
            "sno" : "VS1", "code" : 210, "name" : "Programming I", "credits" : 1
        ]
    ,
    "totalCredits" : 30,
    "semester" : 3
    

八个这样的字典存储在“主题”中。我想在“humanities”、“applied”等每个元素中添加另一个键值对“marks”:0。 这是我正在使用的代码,例如“人文”

    for i in 0..<self.subjects.count
        
            for j in 0..<self.subjects[i]["humanities"]!.count
            
                self.subjects[i]["humanities"]![j]["marks"] = 0
            
        

这就是我得到错误的地方。

编辑 2:添加了附加声明

【问题讨论】:

请添加您正在尝试的代码.. 由于值语义,您需要将字典作为var,添加键/值对并将字典分配回数组。 @Prashant 我已添加代码 科目声明和学期仍然缺失。这些是解决您的问题的重要部分。请帮助我们帮助您。 我很抱歉。 “学期”与我遇到的问题无关。我添加了“主题”的声明 【参考方案1】:

主要问题是您不会像在数组中那样为字典分配值。

如果您像这样访问字典中的值:

var dictionaryValues = dictionary.values

然后尝试更改该数组 'dictionaryValues' 中的值,您正在尝试错误地更新字典。

更改字典中条目的方法是根据关联的键分配值。

所以我知道要更改的值的键,您可以像这样分配新值:

let key = "keyForValueYouWishToChange"
let newValue: AnyObject = 1

for (index, dictionary) in arrayOfDictionaries.enumerate() 
    var mutableDictionary = dictionary
    mutableDictionary[key] = newValue //this is how you assign to dictionaries
    arrayOfDictionaries[index] = mutableDictionary
 

另外,将您的字典更改为 var 而不是 let,以便它是可变的

【讨论】:

哦,是的,愚蠢的错误。我在旅行时在手机上使用堆栈溢出,所以有时可能会马虎【参考方案2】:

很难理解你真正想要做什么。您不会在内存中保留[String : [String : [[String : Any]]]] 之类的结构并将内容修改为该结构,这很可能是您收到此错误的原因。你必须从这个结构中“提取”并使用它。如果你想把它重新转换成 JSON,你必须再次序列化它,反之亦然。 首先,我将向您展示如何从 JSON 中获取单个主题:

// Mockup String
let jsonString = " \"subjects\" :  \"humanities\" : [ \"sno\" : \"TH5\", \"code\" : 205, \"name\" :     \"Mathematics III\", \"credits\" : 4 ], \"applied\" : [ \"sno\" : \"TH3\", \"code\" : 203, \"name\" : \"Power     Apparatus\", \"credits\" : 4, \"sno\" : \"TH4\", \"code\" : 204, \"name\" : \"Electrical Measurements\",     \"credits\" : 4 ], \"core\" : [ \"sno\" : \"TH1\", \"code\" : 201, \"name\" : \"Electronics I\", \"credits\" :     4, \"sno\" : \"TH2\", \"code\" : 202, \"name\" : \"Circuits and Systems\", \"credits\" : 4 ], \"theory\" : [     \"sno\" : \"TH1\", \"code\" : 201, \"name\" : \"Electronics I\", \"credits\" : 4, \"category\" : \"C\",     \"sno\" : \"TH2\", \"code\" : 202, \"name\" : \"Circuits and Systems\", \"credits\" : 4, \"category\" : \"C\",     \"sno\" : \"TH3\", \"code\" : 203, \"name\" : \"Power Apparatus\", \"credits\" : 4, \"category\" : \"A\",     \"sno\" : \"TH4\", \"code\" : 204, \"name\" : \"Electrical Measurements\", \"credits\" : 4, \"category\" :     \"A\", \"sno\" : \"TH5\", \"code\" : 205, \"name\" : \"Mathematics III\", \"credits\" : 4, \"category\" :     \"H\" ], \"practical\" : [ \"sno\" : \"PR1\", \"code\" : 206, \"name\" : \"Electronics I\", \"credits\" : 2,     \"sno\" : \"PR2\", \"code\" : 207, \"name\" : \"Power Apparatus\", \"credits\" : 2, \"sno\" : \"PR3\",     \"code\" : 208, \"name\" : \"Electrical Measurements\", \"credits\" : 2, \"sno\" : \"PR4\", \"code\" : 209,     \"name\" : \"Machine Drawing\", \"credits\" : 3, \"sno\" : \"VS1\", \"code\" : 210, \"name\" : \"Programming     I\", \"credits\" : 1 ] , \"totalCredits\" : 30, \"semester\" : 3 "

// use a function to directly retrieve a single subject
func getSubject(subject: String) -> [String: Any]? 

    // use some guards to keep the nesting depth minimal

    // read the json string
    let data = jsonString.data(using: .utf8)
    guard data != nil else 
        return nil
    

    // try to parse the json
    let parsedJson = try? JSONSerialization.jsonObject(with: data!) as? [String: Any]
    guard parsedJson != nil else 
        return nil
    

    // read the subjects
    if let jsonDictionary = parsedJson! 
        let subjects = jsonDictionary["subjects"] as? [String: Any]
        guard subjects != nil else 
            return nil
        

        // get a single subject and interpret it as array
        if let singleSubject = subjects![subject] as? [Any] 
            // check if it contains elements
            if singleSubject.count > 0 
                // return the first (and only) entry as dictionary
                return singleSubject[0] as? [String: Any]
            
        
    

    return nil


if var humanities = getSubject(subject: "humanities") 

    // add a new entry
    humanities["marks"] = 0

    // print out all entries to check
    for (key, value) in humanities 
        print("\(key): \(value)")
    

打印:

name: Mathematics III
marks: 0
sno: TH5
code: 205
credits: 4

【讨论】:

我将整个数据保存在一个 let 常量中。我将字典数组的各个元素保存在类顶部声明的变量中。

以上是关于如何在 Swift 中将键值对添加到类型为 [String:AnyObject] 的字典中?的主要内容,如果未能解决你的问题,请参考以下文章

在scala中将键值对添加到Map

我可以在 for 循环中将键值对添加到 NSarray 或字典吗?

如何在 JavaScript 中将 Object 转换为 Array [] 键值对

如何在php中将对象数组转换为键值对

如何在 Scala 中将元素添加到 Map 中,其中键是字符串,值是 List[String]

如何在 php 中将数组值作为键值对插入到数据库表中