UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: grouped table by object's date property

Forums > SwiftUI

I have Person class,

class Person: Identifiable {
    var name: String
    var DOB: Date

    init(name: String, DOB: Date) {
        self.name = name
        self.DOB = DOB
    }
}

I have a PersonModelView which has an array of Persons.

var persons: [Person] = []

My SwiftUI View has a PersonModelView.

How would I go about displaying the persons in a List grouped by months based on each Person's upcoming birthdays?

The List would would looks this:

This month:
    Jane
    Paul
    Kevin
November, 2020:
    Sally
    Phoebe
    Cecil
December, 2020:
    Harold
    Ben
January, 2021:
    Cathy

Thanks, Gonzalo

2      

hi,

if you just want the persons collected by month, from 1 through 12, use a dictionary and then rearrange its values (each value has type [Person]) by key into an array (which will have type [[Person]]. For example:

func personsByMonth() -> [[Person]] {
  guard !persons.isEmpty else { return [] }
  let dictionaryByMonth = Dictionary(grouping: persons, by: { $0.month })
  let months = Array(1...12) // rotate this array if you want to go from October to September
  return months.compactMap({ dictionaryByMonth[$0] })
}

the code above assumes that Person has a computed property month, an integer from 1 to 12, which you can compute from the DOB using its DateComponents. the compactMap operator is needed because some keys will not exist in the dictionary; only non-empty arrays of people by month will be returned as a result.

now you can display them in a grouped list:

List {
  ForEach(personsByMonth(), id: \.self) { personsInMonth in
    Section(header: Text(headerText(for: personsInMonth))) {
      ForEach(personsInMonth) { person in
        Text(person.name)
      } // end of ForEach
    } // end of Section
  } // end of ForEach
} // end of List

to figure out an appropriate headerText(for: personsInMonth) function, just recognize that all persons in personsInMonth share the same birthday month; so just read the month of any one of them, e.g., personsInMonth[0].month.

hope that helps,

DMG

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.