How to check consecutive weekdays in an array

百般思念 提交于 2021-01-27 15:58:47

问题


I have a function below (datesCheck) that cycles through an array of dates and firstly removes any entries if there is more than one a day and then checks whether the dates are consecutive within the array, returning the number of consecutive days from the current date.

func datesCheck(_ dateArray: [Date]) -> Int {
    let calendar = Calendar.current

    let uniqueDates = NSSet(array: dateArray.map { calendar.startOfDay(for: $0) }).sorted {
    ($0 as AnyObject).timeIntervalSince1970 > ($1 as AnyObject).timeIntervalSince1970
    } as! [Date]
         var lastDate = calendar.startOfDay(for: Date())
         var i = 0

     while i < uniqueDates.count && uniqueDates[i].compare(lastDate) == .orderedSame {
              lastDate = (calendar as NSCalendar).date(byAdding: .day, value: -1, to: lastDate, options: [])!
              i += 1
    }
    numberOfConsecutiveDays = i
    return i
}

This function works well but I want to only apply this to dates that are Monday – Friday, with the consecutive dates checker checking Friday – Monday, effectively ignoring saturday and sunday. I have tried to achieve this using calendar.components but cannot find a way to ignore weekends when checking if the dates are consecutive excluding weekends.

 let today = Date()
 let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)
 let components = calendar!.components([.weekday], fromDate: today)

 if components.weekday == 2 {
           print("Monday")
 } else {
           print("Monday")
 }

回答1:


A couple points:

  • Since you don't need weekends, filter them out

  • Your function is non-deterministic, since it uses the current time (Date()). The result is theoretically different for every run. I added a second parameter fromDate to make it deterministic.


func datesCheck(_ dates: [Date], fromDate: Date = Date()) -> Int {
    let calendar = Calendar.current
    let weekdays = dates.map { calendar.startOfDay(for: $0) }
                    .filter { 2...6 ~= calendar.component(.weekday, from: $0) } 
    let uniqueDates = Set(weekdays).sorted(by: >)

    var i = 0       
    var lastDate = calendar.startOfDay(for: fromDate)
    while i < uniqueDates.count && uniqueDates[i] == lastDate {
        switch calendar.component(.weekday, from: uniqueDates[i]) {
        case 2:
            // When the lastDate is a Monday, the previous weekday is 3 days ago
            lastDate = calendar.date(byAdding: .day, value: -3, to: lastDate)!
        default:
            // Otherwise, it's 1 day ago
            lastDate = calendar.date(byAdding: .day, value: -1, to: lastDate)!
        }
        i += 1
    }
    return i
}

Test:

let dates = [
    DateComponents(calendar: .current, year: 2017, month: 8, day: 29).date!,
    DateComponents(calendar: .current, year: 2017, month: 8, day: 28).date!,
    DateComponents(calendar: .current, year: 2017, month: 8, day: 25).date!,
    DateComponents(calendar: .current, year: 2017, month: 8, day: 24).date!,
    DateComponents(calendar: .current, year: 2017, month: 8, day: 22).date!,
    DateComponents(calendar: .current, year: 2017, month: 8, day: 21).date!
]
let today = DateComponents(calendar: .current, year: 2017, month: 8, day: 29).date!
print(datesCheck(dates, fromDate: today)) // 4

The code prints 4 since the gap between the 28th and 25th is ignored according to the weekend rule.



来源:https://stackoverflow.com/questions/45941200/how-to-check-consecutive-weekdays-in-an-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!