[英]How can I compare times in an array?
我正在構建公交車到達時間應用程序。 它需要一個傳遞兩個參數的函數:用戶位於的當前停靠站,以及用戶想要到達的目標停靠站。 到達時間是硬編碼的,並且沒有任何“實時到達”時間。
我遇到的問題是嘗試比較時間並確定下一輛公共汽車何時到達。 時間存儲在數組中,無法更改。
例如,如果數組如下:[“ 08:00”,“ 23:00”,“ 01:00”,“ 04:00”],並且也讓我們說當前時間是“ 16:00” ,該函數返回的時間為“ 23:00”。 簡單吧? 我已經使用擴展類對此位進行了編碼,可以在我的Pastebin中找到它。
但是,當時間進入“第二天”時會出現問題,因此,如果時間是“ 00:00”,我不知道如何返回“ 01:00”,因為我的函數只會返回第一次在數組(“ 08:00”)中,因為“ 00:00”低於“ 08:00”。
import UIKit
// Replace the variable currentTime with a value of "00:00" and see how my function returns "08:17" which is wrong. I want the function to return "00:03" since it is the next time in the array. Or if the current time is "01:00" it should return "01:03". BUT, if the current time is "01:04" or greater, it should return the first time in the array "08:17"
// Hard coded bus arrival times
let array: [String] = ["08:17", "08:37", "08:57", "09:21", "09:51", "10:21", "10:51", "11:21", "11:51", "12:21", "12:51", "13:21", "13:51", "14:21", "14:51", "15:21", "15:51", "16:21", "16:51", "17:21", "17:51", "18:21", "18:51", "19:21", "19:51", "21:03", "22:03", "23:03", "00:03", "01:03"]
// Date object stuff
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let date = Date()
let calender = Calendar.current
let components = calender.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
let year = components.year
let month = components.month
let day = components.day
let hour = components.hour
let minute = components.minute
let second = components.second
// Returns current time in a "HH:mm:ss" format
func getTimeString() -> String {
var minuteAsString = String(minute!)
if minute! < 10 {
minuteAsString = "0\(String(minute!))"
}
let timeString = String(hour!) + ":" + minuteAsString
return timeString
}
func getNextBus(_ currentStop: String,_ destinationStop: String) -> String {
var listToUse: [String] = []
let currentTime = getTimeString()
print(currentTime)
switch (currentStop, destinationStop) {
case ("stop1", "stop2"):
listToUse = array
default: ()
}
print(listToUse)
for busTime in listToUse {
if currentTime < busTime {
return busTime
}
}
return "Error! No time found."
}
print(getNextBus("stop1", "stop2"))
// Time class which allows times to be compared and equated
class Time: Comparable, Equatable {
init(_ date: Date) {
//get the current calender
let calendar = Calendar.current
//get just the minute and the hour of the day passed to it
let dateComponents = calendar.dateComponents([.hour, .minute], from: date)
//calculate the seconds since the beggining of the day for comparisions
let dateSeconds = dateComponents.hour! * 3600 + dateComponents.minute! * 60
//set the varibles
secondsSinceBeginningOfDay = dateSeconds
hour = dateComponents.hour!
minute = dateComponents.minute!
}
init(_ hour: Int, _ minute: Int) {
//calculate the seconds since the beggining of the day for comparisions
let dateSeconds = (hour * 3600 + minute * 60)
//set the variables
secondsSinceBeginningOfDay = dateSeconds
self.hour = hour
self.minute = minute
}
var hour : Int
var minute: Int
var date: Date {
//get the current calender
let calendar = Calendar.current
//create a new date components.
var dateComponents = DateComponents()
dateComponents.hour = hour
dateComponents.minute = minute
return calendar.date(byAdding: dateComponents, to: Date())!
}
/// the number or seconds since the beginning of the day, this is used for comparisions
public let secondsSinceBeginningOfDay: Int
static func < (lhs: Time, rhs: Time) -> Bool {
return lhs.secondsSinceBeginningOfDay < rhs.secondsSinceBeginningOfDay
}
}```
假設我們有這個數組:
let array = ["08:00", "23:00", "01:00", "04:00"]
處理“公交時間”的一種更方便的方法是定義一個結構,如下所示:
struct BusTime: Comparable, CustomStringConvertible {
let hour : Int
let minute : Int
static func < (lhs: BusTime, rhs: BusTime) -> Bool {
return (lhs.hour, lhs.minute) < (rhs.hour, rhs.minute)
}
var description: String {
get {
let formatter = NumberFormatter()
formatter.minimumIntegerDigits = 2
return formatter.string(for: hour)! + ":" + formatter.string(for: minute)!
}
}
}
注意:在剩下的答案中,為簡潔起見,我將強制展開)
讓我們創建一個BusTime
的排序數組:
let busTimes: [BusTime] = array.map { str in
return BusTime(hour: Int(str.prefix(2))!, minute: Int(str.suffix(2))!)
}
var sortedBusTimes = busTimes.sorted()
我們還定義一個變量nextBus
,它代表下一個公交時間:
var nextBus: BusTime = sortedBusTimes[0]
現在,讓我們創建一個與當前日期相對應的時間:
let nowComps = Calendar.current.dateComponents([.hour, .minute], from: Date())
let now = BusTime(hour: nowComps.hour!, minute: nowComps.minute!)
通過二進制搜索,我們將能夠在O(log(n))中找到下一個公交車時間:
var low = sortedBusTimes.startIndex
var high = sortedBusTimes.endIndex
while low < high {
let middle = low + (high - low)/2
let middleTime = sortedBusTimes[middle]
if middleTime == now {
low = middle
break
} else if middleTime < now {
low = middle + 1
} else if now < middleTime {
high = middle
}
}
if low != sortedBusTimes.endIndex, high != 0 {
nextBus = sortedBusTimes[low]
}
middle
的定義可以這樣簡單:
let middle = low + (high - low)/2
但是,采取這種文章考慮。
最后,讓我們檢查一下:
print(nextBus)
在撰寫此答案時,它是17:52。 因此,在控制台中顯示的結果是:
23:00
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.