So if have an array of ToDos and the Todo objects have the properties due(Bool) which has the info if the ToDo has a due date; dueDate(Date) which is an optional so if due is true dueDate != nil, if due is false dueDate = nil; creationDate(Date): Date of Todo creation. Furthermore there is a property isChecked(Bool) which gives answer, if the ToDo is done or not. Now I want to sort the array of ToDos in this order:
- isChecked = false, closest dueDate
- isChecked = false, dueDate = nil, closest creationDate
- isChecked true, closest creationDate
How can I get this array sorted after the order above with the optional property of dueDate?
CodePudding user response:
If I understand you properly, you have this kind of structure:
struct Item {
let isChecked: Bool
let creationDate: Date
let dueDate: Date?
}
and I think by "closest" you mean that you want the items sorted by being close to a specific Date
.
This could be done in the following manner. Let's define a helper method first:
extension Item {
func getOrderingClosestTo(_ date: Date) -> (Int, Int, TimeInterval) {
return (
// items that are not checked are "smaller", they will be first
isChecked ? 1 : 0,
// items with dueDate are smaller, they will be first
dueDate != nil ? 0 : 1,
// items closer to "date" will be smaller
abs((dueDate ?? creationDate).timeIntervalSince(date))
)
}
}
Then you can call:
let myDate: Date = ...
let items: [Item] = ...
let sortedItems = items.sorted { $0.getOrderingClosestTo(myDate) < $1.getOrderingClosestTo(myDate) }