Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update swift dictionary value

I rewrite this code from php. And I find it difficult to make it work in swift.

var arrayOfData = [AnyObject]()

for index in 1...5 {
    var dict = [String: AnyObject]()
    dict["data"] = [1,2,3]
    dict["count"]  = 0

    arrayOfData.append(dict)
}

for d in arrayOfData {

    let data = d as AnyObject

    // I want to update the "count" value
    // data["count"] = 8
    print(data);
    break;
}
like image 855
Ben Avatar asked Dec 19 '22 16:12

Ben


2 Answers

Presumably, you want to update the value inside of arrayOfData when you assign data["count"] = 8. If you switch to using NSMutableArray and NSMutableDictionary, then your code will work as you want. The reason this works is that these types are reference types (instead of value types like Swift arrays and dictionaries), so when you're working with them, you are referencing the values inside of them instead of making a copy.

var arrayOfData = NSMutableArray()

for index in 1...5 {
    var dict = NSMutableDictionary()
    dict["data"] = [1,2,3]
    dict["count"] = 0

    arrayOfData.addObject(dict)
}

for d in arrayOfData {
    let data = d as! NSMutableDictionary
    data["count"] = 8
    print(data)
    break
}
like image 83
vacawama Avatar answered Jan 06 '23 22:01

vacawama


Assuming your array has to be of form '[AnyObject]' then something like this:

var arrayOfData = [AnyObject]()

for index in 1...5 {
    var dict = [String: AnyObject]()
    dict["data"] = [1,2,3]
    dict["count"]  = 0

    arrayOfData.append(dict)
}

for d in arrayOfData {

    // check d is a dictionary, else continue to the next 
    guard let data = d as? [String: AnyObject] else { continue }

    data["count"] = 8
}

But preferably your array would be typed as an array of dictionaries:

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

for index in 1...5 {
    var dict = [String: AnyObject]()
    dict["data"] = [1,2,3]
    dict["count"]  = 0

    arrayOfData.append(dict)
}

for d in arrayOfData {
    // swift knows that d is of type [String: AnyObject] already
    d["count"] = 8
}

EDIT:

So the issue is that when you modify in the loop, you're creating a new version of the dictionary from the array and need to transfer it back. Try using a map:

arrayOfData = arrayOfData.map{ originalDict in
    var newDict = originalDict
    newDict["count"] = 8
    return newDict
}
like image 34
SeanCAtkinson Avatar answered Jan 06 '23 23:01

SeanCAtkinson