Swift 4
I have an array that will have random days of the week text in it. For example
var daysOfWeek: [String] = [] // ["Tuesday", "Thursday" , "Sunday", "Friday"]
I want to be able to sort them like: Sunday, Monday, Tuesday, ect...
Im not sure if this is the right approach, but I tried this..
let dateFormatter = DateFormatter()
for element in daysOfWeek {
print(dateFormatter.weekdaySymbols[element])
}
Which throws an error:
value of optional type '[String]?' must be unwrapped to refer to member 'subscript' of wrapped base type
Im fairly new to Xcode and Swift
Is this the right way to do it? if so, how can I fix the error?
If this isn't the right way to do it, then what is? I appreciate any help
You can create a dictionary like this, that corresponds each string to a numerical value:
let weekDayNumbers = [
"Sunday": 0,
"Monday": 1,
"Tuesday": 2,
"Wednesday": 3,
"Thursday": 4,
"Friday": 5,
"Saturday": 6,
]
And then you can just sort by this:
weekdays.sort(by: { (weekDayNumbers[$0] ?? 7) < (weekDayNumbers[$1] ?? 7) })
This will order non-weekday strings at the end.
Also note that different areas of the world have a different start of week. They might order things differently.
Here is the way to do it:
let week = DateFormatter().weekdaySymbols!
print(week) //["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
This way, the day names and the first day of the week will be set automatically based on the current locale and system settings. For example:
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "fr-FR")
let week = formatter.weekdaySymbols!
print(week) //["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"]
To sort an array of some day names:
let week = DateFormatter().weekdaySymbols!
var daysOfWeek: [String] = ["Tuesday", "Thursday" , "Sunday", "Friday"]
daysOfWeek.sort { week.firstIndex(of: $0)! < week.firstIndex(of: $1)!}
print(daysOfWeek) //["Sunday", "Tuesday", "Thursday", "Friday"]
I am force-unwrapping here just for brevity. You could check that all strings in daysOfWeek are valid using:
var daysOfWeek: [String] = ["Tuesday", "Thursday" , "Sunday", "Friday"]
let week = DateFormatter().weekdaySymbols!
guard Set(daysOfWeek).isSubset(of: week) else {
fatalError("The elements of the array must all be day names with the first letter capitalized")
}
To make the above solution quicker, as suggested by Mr Duncan, here is an alternative approach:
let week = DateFormatter().weekdaySymbols!
var dayDictionary: [String: Int] = [:]
for i in 0...6 {
dayDictionary[week[i]] = i
}
var daysOfWeek: [String] = ["Tuesday", "Thursday" , "Sunday", "Friday"]
daysOfWeek.sort { (dayDictionary[$0] ?? 7) < (dayDictionary[$1] ?? 7)}
print(daysOfWeek) //["Sunday", "Tuesday", "Thursday", "Friday"]
Using strings as day name identifiers is prone to error. A safer approach uses enums:
enum WeekDay: String {
case first = "Sunday"
case second = "Monday"
case third = "Tuesday"
case fourth = "Wednesday"
case fifth = "Thursday"
case sixth = "Friday"
case seventh = "Saturday"
}
let week: [WeekDay] = [.first, .second, .third, .fourth, .fifth, .sixth, .seventh]
var dayDictionary: [WeekDay : Int] = [:]
for i in 0...6 {
dayDictionary[week[i]] = i
}
var daysOfWeek: [WeekDay] = [.third, .fifth , .first, .sixth]
daysOfWeek.sort { (dayDictionary[$0] ?? 7) < (dayDictionary[$1] ?? 7)}
print(daysOfWeek.map {$0.rawValue}) //["Sunday", "Tuesday", "Thursday", "Friday"]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With