2017-08-29 4 views
2

私は以下の関数(datesCheck)を使って日付の配列を循環させ、最初に複数の日がある場合はすべてのエントリを削除し、配列内で日付が連続しているかどうかをチェックします現在の日付から連続した日数を返します。月曜日を効果的に土曜日と日曜日を無視 - 連続した日付が金曜日チェックチェッカーで、金曜日 -配列で連続する平日をチェックする方法

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 
} 

この機能はうまく動作しますが、私は唯一の月曜日の日付にこれを適用します。私はcalendar.componentsを使用してこれを達成しようとしましたが、週末を除いて日付が連続しているかどうかをチェックするときに週末を無視する方法を見つけることができません。

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

FYI - なぜあなたは 'Date'と' NSDate'の両方を使用していますか?なぜあなたは 'NSCalendar'と' Calendar'の両方を使っていますか? Swift 2クラスではなく、Swift 3クラスを使用します。 – rmaddy

+0

あなたは正しいです。私はコードを更新しました。 –

+0

あなたはしましたか?私はまだ多くの 'NSCalendar'を見ています。私は 'NSSet'を見る。私は 'AnyObject'の不要な使い方を見ています。まだSwift 2のコードがたくさんあります。実際にコンパイルされる実際のSwift 3コードを投稿してください。 – rmaddy

答えて

1

カップルのポイント:

  • あなたはそれが現在の時刻(Date())を使用していますので、あなたの関数は、非決定的である

  • をそれらを除外し、週末を必要としないので、 。結果は理論的にはすべての実行で異なります。確定的にするために、第2のパラメータfromDateを追加しました。


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 
} 

試験:

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 

コードプリント4 28日と25日との間のギャップを週末の規則に従って無視されるからです。

+0

これは優れています。どうもありがとうございました。エレガントなソリューション! –

関連する問題