2017-07-14 48 views
1

我见过没有太大的帮助几个类似的SO问题类型斯威夫特不可改变的表达,无法指定

我试图更新availabilityTimes为周一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" ] 
        ] 

这里是我的代码,当我打电话了以下的功能,我在代码行0收到一条错误消息

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

     } 
    } 
} 
+1

你正在争取一个具有值语义的Swift集合类型。使用自定义结构或类。它使生活变得更容易。 – vadian

+0

@vadian,如果你能详细说明,那会很棒。 – user44776

回答

2

根据我的评论我的意思是在开始和结束时间的自定义结构Times和结构DailyTimes具有所需性能和变异函数来更新Times阵列:

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

现在创建所述availableTimes词典:

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")])] 

timesArray数组:

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")] 

由于Times阵列的Monday已经包含timesArray让我们更新的值Tuesday

availableTimes["Tuesday"]?.update(times:timesArray) 

最后证明这一点

print(availableTimes["Tuesday"]?.times) 

另一项改进可以使用DateComponents代替String小号为时代。

+0

谢谢,详细的解释,我会去你的建议。 – user44776

1

在夫特,一个Dictionary是一个结构,它是一个值类型。考虑像原始类型的值类型,如int

如果你有这样的:

int a = 0 
int b = a 

然后B获得的价值,它们是不相同的。

所以,当你循环字典时,你的(键,值)对实际上不是字典中的东西,它们只是具有相同的值。迭代它时,不要改变值或引用也很重要。这可能会导致奇怪的错误。

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 
    } 
} 
+0

感谢您的明确解释。因为我想更新一个特定日子的时间,这个'newtimes [key1] = timesArray作为AnyObject'是'newtimes [day] [key1] = timesArray as AnyObject'吗? 。当我尝试'newtimes [day] [key1]'我得到类似的错误'不能分配给Any类型的不可变表达式' – user44776

+0

正如@vadian所提到的,当正确的解决方案可能是创建自己的结构它可能包装一些字典或使用类来获得引用语义的好处。如果你来自objc,你也可以直接使用'NSDictionary'来获得引用语义,但是你的类型安全性很差。 –

+0

@ user44776,我最后一次更新了代码,完整的重写显示了一个更简单的方法。我也使用了一些Swift特性来使一切更清晰。 –