Swift - Sort array by optionals

267 Views Asked by At

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:

  1. isChecked = false, closest dueDate
  2. isChecked = false, dueDate = nil, closest creationDate
  3. isChecked true, closest creationDate

How can I get this array sorted after the order above with the optional property of dueDate?

1

There are 1 best solutions below

2
On BEST ANSWER

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) }