Ben
Ben

Reputation: 1914

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;
}

Upvotes: 6

Views: 28537

Answers (3)

Justin Meiners
Justin Meiners

Reputation: 11113

The most efficient way would be to find the index of the relevant values entry, and then replace that entry. The index is essentially just a pointer into the hash table, so it's better than looking up by key twice:

To update all the entries, you can loop through the indices one at a time:

for i in dictionary.values.indices {
   dictionary.values[i].property = ...
}

To update a particular key, use:

let indexToUpdate = dictionary.values.index(forKey: "to_update") 
dictionary.values[i].property = ...

Upvotes: 0

SeanCAtkinson
SeanCAtkinson

Reputation: 763

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
}

Upvotes: 6

vacawama
vacawama

Reputation: 154513

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
}

Upvotes: 6

Related Questions