1

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?

2
  • 1
    Is the question about how to sort the objects or how to handle an optional Date when sorting? And did you try something yourself to solve this? Commented May 10, 2022 at 20:26
  • Is is mostly about how to handle an optional and sort the objects with a value for the optional First with descending order Commented May 10, 2022 at 21:28

1 Answer 1

1

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) }
Sign up to request clarification or add additional context in comments.

2 Comments

Wow thank you for the fast reply. It mostly works fine. Just when the Due Date for example was yesterday than the Todo is sorted last but should be at the top and the ToDo with isChecked = true seem not to be sorted correctly: first item from isChecked with date of today should be before second item with creationDate of yesterday. I hope thats understandable. I will try to retrace your solution :D
@Timothy The first one is probably due to the abs I have used there - it doesn't see a difference between yesterday and tomorrow, it just takes the closest. I cannot test more without actual data.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.