简体   繁体   中英

How to add a key value pair to a dictionary of type [String:AnyObject] in Swift?

I have stored the contents of a JSON file in a array of dictionaries of type [[String:AnyObject]]. I want to add a new key-value pair to each item in the [String:AnyObject] dictionary. I keep getting the error : Cannot assign to immutable expression of type 'AnyObject?!'Is there any way around this?

subjects has been declared as follows:

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

EDIT: Apologies for not posting the code.So, this is one of the elements of the [[String:AnyObject]] array

   { "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
    }

Eight such dictionaries are stored in 'subjects'. I want to add another key-value pair "marks" : 0 to each element in "humanities", "applied" and so on. This is the code I am using, for example, for "humanities"

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

And that's where I get the error.

EDIT 2: Added additional declaration

The main problem is that you don't assign values to dictionaries in the same what you do in arrays.

If you are accessing the values in the dictionaries like this:

var dictionaryValues = dictionary.values

and then trying to change the values in that array 'dictionaryValues' you are trying to update the dictionary incorrectly.

The way you change an entry in a dictionary is by assigning the value according to its associated key.

So I you know the key(s) for the values you want to change you can assign the new values like this:

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
 }

Also, change your dictionary to a var rather than a let so it is mutable

It's hard to understand what you really want to do. You don't keep a structure like [String : [String : [[String : Any]]]] in memory and modify stuff right into that, that's most probably why you get this error. You have to "extract" from this structure and work with that. If you want it back into JSON, you have to serialise it again, doing it the other way round. To give you a start, I'll show you how to get a single subject from your 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)")
    }
}

prints:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM