Search code examples
iosarraysswiftsortingtableview

Complex sorting in tableView


I have two arrays:

var sections: [SectionContent] = []
var cells: [CellContent] = []

Of those two arrays, one is nested inside the other one:

struct SectionContent {
    let sectionDate: Date
    let sectionContent: [CellContent]
}

struct CellContent {
    let cellDate: Date?
    var formattedDate: String {
        guard let text = cellDate else { return "" }
        return DateFormatter.stringDate.string(from: text)
    }
}

extension DateFormatter {
    static let stringDate: DateFormatter = {
        let formatterDate = DateFormatter()
        formatterDate.dateFormat = "MMM d, h:mm a"
        return formatterDate
    }()
}

The 'sections' array displays the date as the section header in tableView.

The 'cells' array displays the respective data assigned to that date.

The date is set in a separate viewController from which I do the unwindSegue to the first viewController.

I managed to sort the sections by date thru including this code inside of the unwindSegue:

sections.sort { $0.sectionDate < $1.sectionDate }

Question: Given my configuration, how do I sort cells within one section by the corresponding time (earlier time at the top and later at the bottom)?

enter image description here

Edit: This is how I construct the Section:

func sortByDate() {
    sections.removeAll()
    let dates = cells.reduce(into: Set<Date>()) { result, cells in
        let date = Calendar.current.startOfDay(for: cells.cellDate!)
        result.insert(date) }
    for date in dates {
        let dateComp = Calendar.current.dateComponents([.year, .month, .day], from: date)
        var sortedContent: [CellContent] = []
        cells.forEach { cells in
            let contComp = Calendar.current.dateComponents([.year, .month, .day], from: cells.cellDate!)
            if contComp == dateComp {
                sortedContent.append(cells) } }
        let newSection = SectionContent(sectionDate: date, sectionContent: sortedContent)
        sections.append(newSection) } }

Solution

  • sort the sections as you're already doing it

    //sort the sections
    sections.sort { $0.sectionDate < $1.sectionDate }
    

    then sort the contents like this

    //sort the contents
    for index in 0..<sections.count {
        sections[index].sectionContent.sort { $0.cellDate ?? .now < $1.cellDate ?? .now }
    }
    

    note that you must change sectionContent to a var for the second sort to work

    struct SectionContent {
        let sectionDate: Date
        var sectionContent: [CellContent] //<--- must be var not let
    }