Skip to content

Instantly share code, notes, and snippets.

@davejlin
Last active April 21, 2017 18:09
Show Gist options
  • Save davejlin/3e9e43aa8afc7ed37ba17420741225aa to your computer and use it in GitHub Desktop.
Save davejlin/3e9e43aa8afc7ed37ba17420741225aa to your computer and use it in GitHub Desktop.
applyLimit limit number of calendar entries based on calendar date with performance results
// 1.361s
func applyLimit(toData data: [EkEventDao]) -> [EkEventDao] {
var datesDict:[String:Int] = [:]
var limitedData: [EkEventDao] = []
for datum in data {
let dateKey = datum.startDate.startOfDay.description
let value = datesDict[dateKey]
if value == nil { datesDict[dateKey] = 0 }
guard datesDict[dateKey]!<Const.MAX_ENTRIES_PER_DAY else { continue }
datesDict[dateKey]! += 1
limitedData.append(datum)
}
return limitedData
}
// 1.411s
func applyLimit(toData data: [EkEventDao]) -> [EkEventDao] {
var datesDict:[String:Int] = [:]
return data.flatMap {
let dateKey = $0.startDate.startOfDay.description
let value = datesDict[dateKey]
if value == nil { datesDict[dateKey] = 0 }
guard datesDict[dateKey]!<Const.MAX_ENTRIES_PER_DAY else { return nil }
datesDict[dateKey]! += 1
return $0
}
}
// 2.618s
func applyLimit(toData data: [EkEventDao]) -> [EkEventDao] {
let uniqueDates = Set(data.map{$0.startDate.startOfDay})
var datesDict:[String:Int] = [:]
for dates in uniqueDates {
datesDict[dates.description] = 0
}
return data.flatMap {
let dateKey = $0.startDate.startOfDay.description
guard datesDict[dateKey]!<Const.MAX_ENTRIES_PER_DAY else { return nil }
datesDict[dateKey]! += 1
return $0
}
}
// 4.858s
func applyLimit(toData data: [EkEventDao]) -> [EkEventDao] {
var dataLimited: [EkEventDao] = []
let uniqueDates = Set(data.map{$0.startDate.startOfDay})
for date in uniqueDates {
dataLimited += data.filter({date.compare($0.startDate.startOfDay) == .orderedSame })
.prefix(Const.MAX_ENTRIES_PER_DAY)
}
return dataLimited
}
struct EkEventDao {
let title: String
let eventId: String
let location: String?
let startDate: Foundation.Date
let endDate: Foundation.Date
let allDay: Bool
}
extension Foundation.Date {
var startOfDay: Foundation.Date {
var components = self.components
components.hour = 0
components.minute = 0
components.second = 0
return Calendar.current.date(from: components)!
}
}
struct Const {
static let MAX_ENTRIES_PER_DAY = 50
}
// UNIT TEST:
func testLimit() {
var calendarEvents: [EkEventDao] = []
let now = Foundation.Date()
let date1 = now
let date2 = now.addDays(1)
let date3 = now.addDays(2)
let dates = [date1, date2, date3]
let nEntries1 = max(0, Const.MAX_ENTRIES_PER_DAY+1000)
let nEntries2 = max(0, Const.MAX_ENTRIES_PER_DAY+10000)
let nEntries3 = max(0, Const.MAX_ENTRIES_PER_DAY-10)
let nEntries = [nEntries1, nEntries2, nEntries3]
let nExpectedEntries1 = min(nEntries1, Const.MAX_ENTRIES_PER_DAY)
let nExpectedEntries2 = min(nEntries2, Const.MAX_ENTRIES_PER_DAY)
let nExpectedEntries3 = min(nEntries3, Const.MAX_ENTRIES_PER_DAY)
let nExpectedEntries = [nExpectedEntries1, nExpectedEntries2, nExpectedEntries3]
for i in 0..<3 {
for j in 0..<nEntries[i] {
let date = dates[i]
let title = "title \(i),\(j)"
let id = "id\(i),\(j)"
let location = "location \(i),\(j)"
let event = EkEventDao(title:title, eventId:id, startDate: date, endDate: date, location: location)
calendarEvents.append(event)
}
}
var data: [EkEventDao]
self.measure() {
data = CalendarDataImporter().applyLimit(toData: calendarEvents)
}
for i in 0..<3 {
XCTAssertEqual(nExpectedEntries[i], data.filter{$0.startDate.startOfDay == dates[i].startOfDay}.count)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment