Skip to content

Instantly share code, notes, and snippets.

@eugenezuban
Created April 13, 2021 10:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eugenezuban/9e2bc4a066f702d632a4e0d72d871f5b to your computer and use it in GitHub Desktop.
Save eugenezuban/9e2bc4a066f702d632a4e0d72d871f5b to your computer and use it in GitHub Desktop.
A function to help you get the longest contiguous sequence of days from an array of dates. For example, can be used in the habit tracker.
func checkStreak(of dateArray: [Date]) -> Int{
let dates = dateArray.sorted()
// Check if the array contains more than 0 dates, otherwise return 0
guard dates.count > 0 else { return 0 }
// Get full day value of first date in array
let referenceDate = Calendar.current.startOfDay(for: dates.first!)
// Get an array of (non-decreasing) integers
let dayDiffs = dates.map { (date) -> Int in
Calendar.current.dateComponents([.day], from: referenceDate, to: date).day!
}
// Return max streak
return maximalConsecutiveNumbers(in: dayDiffs)
}
// Find maximal length of a subsequence of consecutive numbers in the array.
// It is assumed that the array is sorted in non-decreasing order.
// Consecutive equal elements are ignored.
func maximalConsecutiveNumbers(in array: [Int]) -> Int{
var longest = 0 // length of longest subsequence of consecutive numbers
var current = 1 // length of current subsequence of consecutive numbers
for (prev, next) in zip(array, array.dropFirst()) {
if next > prev + 1 {
// Numbers are not consecutive, start a new subsequence.
current = 1
} else if next == prev + 1 {
// Numbers are consecutive, increase current length
current += 1
}
if current > longest {
longest = current
}
}
return longest
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment