I wanted to unwrap an optional value and update it at the same time to be displayed, but I can’t figure out how to do that because the value is already unwrapped, so I find I have to update it in one If Let clause, and then read out the updated value in another:
if let tallyUpdate = dispatchTally[forProduct.name] {
let updatedTally = tallyUpdate + 1
dispatchTally.updateValue(updatedTally, forKey: forProduct.name)
}
if let tallyUpdated = dispatchTally[forProduct.name] {
print("\(forProduct.name) has been updated to (\(forProduct.name) tally: \(tallyUpdated))")
}
I would have preferred it all in one clause, but it’s a catch22.
Is it possible please?
Lantua
2
Since you’ve already unwrapped the value, and set it to updatedTally, you can just reuse updatedTally (Logically updatedTally would have the same value as tallyUpdated When you print it out):
if let tallyUpdate = dispatchTally[forProduct.name] {
let updatedTally = tallyUpdate + 1
dispatchTally.updateValue(updatedTally, forKey: forProduct.name)
print("\(forProduct.name) has been updated to (\(forProduct.name) tally: \(updatedTally))")
}
1 Like
Use optional map and assign to itself:
1> var tallies:[Int: Int] = [0: 0]
tallies: [Int : Int] = 1 key/value pair {
[0] = {
key = 0
value = 0
}
}
2> tallies[0] = tallies[0].map{ $0 + 1 }
3> tallies
$R0: [Int : Int] = 1 key/value pair {
[0] = {
key = 0
value = 1
}
}
// increments `tallies[0]`, as it should
4> tallies[1] = tallies[1].map{ $0 + 1 }
5> tallies
$R1: [Int : Int] = 1 key/value pair {
[0] = {
key = 0
value = 1
}
}
// does nothing, since `tallies[1]` doesn’t exist
1 Like
Nevin
4
I just want to point out that you can update a dictionary value in-place with optional chaining:
dispatchTally[forProduct.name]? += 1
6 Likes
Ben_Cohen
(Ben Cohen)
5
Note, this will silently do nothing if forProduct.name isn't already present, which is a bit of an unpleasant gotcha unfortunately.
Assuming you aren't pre-seeding the dictionary with keys set to zero, you probably want dispatchTally[forProduct.name, default: 0] += 1
(and if you are, you probably want ! :)
3 Likes
Nevin
6
That’s a funny way to spell “super awesome feature”. :-)
1 Like
Hello again, thank you for your reply.
That was exactly what I did. But the issue was that the value unwrapped was not updated inside the clause, so it only showed the previous value at the time of unwrapping.
Lantua
8
It works fine when I tried in my playground.
It is possible that you use the wrong variable.
There are a few variables in that scope that have similar value after all.
1 Like
Thanks for the conscience piece of code Nevin, I would only need two lines of code to set the values and retrieve it. However, Ben_Coheen is right, I would need to use the “Bang Operator” to get access to the value explicitly, and while only for use in the LLDB, I was taught never to use it. Although Swift will allow be to wrap the value (now an optional, thanks to String Interpolation) with a String: String(describing: productUpdated).
In the end, it turned out that Lantua was right and I had missed one of the constants, as can be seen in my original block of code, where I should have used the past tense when updating the dictionary.
Ms. Swift was a little too complicated for me, but I’m sure one day map will make more sense.
Thank you to everybody for your help.
Learning all the time.