Reputation: 2890
I've seen several similar SO questions without much help,
I am trying to update availabilityTimes
for Monday with timesArray
using the function updateDailyTimes
Example of availabilityTimes
and timesArray
var availabilityTimes = [
"Monday": [ "available" : true,
"times": [
["startTime": "9:00 am", "endTime": "1:30 pm" ],
["startTime": "2:30 pm", "endTime": "6:00 pm" ],
["startTime": "7:30 pm", "endTime": "9:00 pm" ]
]
],
"Tuesday": [ "available" : true,
"times": [
["startTime": "9:00 am", "endTime": "6:00 pm" ]
]
]
]
var timesArray = [
["startTime": "9:00 am", "endTime": "1:30 pm" ],
["startTime": "2:30 pm", "endTime": "6:00 pm" ],
["startTime": "7:30 pm", "endTime": "9:00 pm" ]
]
Here is my code, when I call the below the function, I get an error message cannot assign to immutable expression of type [[String : String]]
in the code line value["times"] as [[String : String]] = timesArray
func updateDailyTimes(day: String, timesArray: [[String:String]]){
guard var updatedTimes = self.availabilityTimes as? [String: AnyObject] else{
return
}
for (key, var value) in updatedTimes {
if key == day{
for (key1, value1) in value as! [String : AnyObject]{
if key1 as String == "times" {
value["times"] as [[String : String]] = timesArray // I get an error message in this line
}
}
}
}
}
Upvotes: 1
Views: 3189
Reputation: 285069
According to my comment I mean a custom struct Times
for the start and end times and a struct DailyTimes
with the required properties and a mutating function to update the Times
array:
struct Times {
let start : String
let end : String
}
struct DailyTimes {
let weekday : String
var available : Bool
var times = [Times]()
mutating func update(times : [Times]) {
self.times = times
}
}
Now create the availableTimes
dictionary:
var availableTimes = ["Monday" : DailyTimes(weekday: "Monday", available: true, times: [Times(start: "9:00 am", end:"1:30 pm"),
Times(start: "2:30 pm", end:"6:00 pm"),
Times(start: "7:30 pm", end:"9:00 pm")]),
"Tuesday" : DailyTimes(weekday: "Tuesday", available: true, times: [Times(start: "9:00 am", end:"6:00 pm")])]
and the timesArray
array:
let timesArray = [Times(start: "9:00 am", end:"1:30 pm"),
Times(start: "2:30 pm", end:"6:00 pm"),
Times(start: "7:30 pm", end:"9:00 pm")]
Since the Times
array of Monday
contains already the values of timesArray
let's update Tuesday
availableTimes["Tuesday"]?.update(times:timesArray)
Finally prove it
print(availableTimes["Tuesday"]?.times)
Another improvement could be to use DateComponents
instead of String
s for the times.
Upvotes: 2
Reputation: 6622
In Swift, a Dictionary
is a struct, which is a value type. Think of value types just like a primitive type such as int
.
If you have this:
int a = 0
int b = a
Then b gets the value of a, they are not identical.
So when you are looping over the dictionary, your (key, value) pair are NOT actually what is in the dictionary, they just have the same value. It's also important not to mutate a value or reference while iterating over it. That can lead to weird bugs.
enum AvailabilityTimeMarker {
case start
case end
}
enum DayOfTheWeek: String {
case monday = "Monday"
case tuesday = "Tuesday"
case wednesday = "Wednesday"
case thursday = "Thursday"
case friday = "Friday"
case saturday = "Saturday"
case sunday = "Sunday"
}
typealias Availability = [DayOfTheWeek : AvailabilityDay]
typealias AvailabilityDay = [String : Any]
typealias AvailabilityArray = [AvailabilityTime]
typealias AvailabilityTime = [AvailabilityTimeMarker : String]
var availabilityTimes: Availability = [
.monday : [ "available" : true,
"times": [
["startTime": "9:00 am", "endTime": "1:30 pm" ],
["startTime": "2:30 pm", "endTime": "6:00 pm" ],
["startTime": "7:30 pm", "endTime": "9:00 pm" ]
]
],
.tuesday : [ "available" : true,
"times": [
["startTime": "9:00 am", "endTime": "6:00 pm" ]
]
]
]
var timesArray: AvailabilityArray = [
[.start : "9:00 am", .end : "1:30 pm" ],
[.start : "2:30 pm", .end : "6:00 pm" ],
[.start : "7:30 pm", .end : "9:00 pm" ]
]
func updateDailyTimes(day: DayOfTheWeek, timesArray: AvailabilityArray) {
let availabilities = self.availabilityTimes
var newtimes = availabilities
if var newDayAvailability = availabilities[day] {
newDayAvailability["times"] = newtimes
newtimes[day] = newDayAvailability
self.availabilityTimes = newtimes// Since we're not using reference semantics, we have to change the entire value
}
}
Upvotes: 1