Home > Software design >  Swift - Sort array by optionals
Swift - Sort array by optionals

Time:05-11

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?

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