I'm trying to modify a dictionary containing a string as the key and an integer as the value. However, when I try to add/minus 1 from the integer, it returns me that error. currCleanup is a Cleanup object, which are clean up sessions people can host. items_collected is a dictionary within a Cleanup object.
@Published var firestore = Firestore.firestore()
@Published var errorMessage: String = ""
@Published private(set) var cleanups: [Cleanup] = []
@Published var currCleanup: Cleanup
//the functions with the error
func addOneItem(itemName: String)
{
for (nam, num) in currCleanup.items_collected {
if nam == itemName {
num = 1 //this is where the error occurs
}
}
db.collection("Cleanups").document(currCleanup.username).updateData(["itemsCollected" : currCleanup.items_collected])
}
func delOneItem(itemName: String)
{
for (nam, num) in currCleanup.items_collected
{
if nam == itemName {
num -= 1 //here too
}
}
db.collection("Cleanups").document(currCleanup.username).updateData(["itemsCollected" : currCleanup.items_collected])
}
CodePudding user response:
When you iterate over value objects, you don't receive a reference to their values, but rather new variables, where the value is copied to.
In your code, num
is not a reference to the dictionary value, but a totally new variable. Even if you add var
before (nam, num)
, it won't work: You'll only change the value of the variable num
, but not the stored-in-dictionary value. Consider this example:
var dict = ["One" : 1,
"Two" : 2,
"Three" : 3]
let keyToChange = "Two"
for var (key, value) in dict {
if key == keyToChange {
value = 4
}
}
print(dict) // ["Two": 2, "Three": 3, "One": 1]
You need to access the dictionary value directly in order to change it:
var dict = ["One" : 1,
"Two" : 2,
"Three" : 3]
let keyToChange = "Two"
for (key, value) in dict {
if key == keyToChange {
dict[key] = 4
}
}
print(dict) // ["Two": 4, "Three": 3, "One": 1]
On the other hand, there's no point in loop, you can just check whether the key exists and change its value directly:
var dict = ["One" : 1,
"Two" : 2,
"Three" : 3]
let keyToChange = "Two"
if dict[keyToChange] != nil {
dict[keyToChange] = 4
}
print(dict) // ["Two": 4, "One": 1, "Three": 3]
In your code it could be this:
if let value = currCleanup.items_collected[itemName] {
currCleanup.items_collected[itemName] = value 1
}
Instead of this:
for (nam, num) in currCleanup.items_collected {
if nam == itemName {
num = 1 //this is where the error occurs
}
}
CodePudding user response:
to increment your array of values at the given itemName
, try this approach:
func addOneItem(itemName: String) {
if currCleanup.items_collected[itemName] != nil {
currCleanup.items_collected[itemName] = currCleanup.items_collected[itemName]! 1
db.collection("Cleanups").document(currCleanup.username).updateData(["itemsCollected" : currCleanup.items_collected])
}
}
Similarly for delOneItem