arraysswiftsortingswift-optionals

Swift - Sort array by optionals


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?


Solution

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