TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

SOLVED: Grouping Dates from Readings from CoreData where the Date is Date()

Forums > SwiftUI

Hi, ?I have a reading that has a Date and is saved as a Date().

so would like to get something like this

Readings for 20/02/2023 Reading time 1 Reading time 2 Reading time 3

Reading for 19/02/2023 Reding time 1 Reding time 2

You get the idea? So any help would be fantastic

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>
            List {
                ForEach(items, id: \.self) { item in
                    let s = String(item.timestamp!.formatted(.dateTime.day().month().year()))
                    //Text("s is \(s)")
                    Section(header: Text("\(s)").font(.title)) {
                        Text("\(item.title!)")
                    }
                }
            }.listStyle(GroupedListStyle())

If the same date is there then creates another section :(. Many thanks in advance Johbn

2      

hi,

you'd first want to group the items so that items with timestamps on the same day are listed together. having a computed variable of this form would help:

var groups: [[Item]] {
     // do the grouping here ...  your example of five items (three on 20/02/2023
     // and two on 19/02/2023) would be returned as an array of arrays:
     // [ [Item, Item, Item], [Item, Item] ]
}

if you get this done, then your SwiftUI view would become

        ForEach(groups, id: \.self) { group in
            Section(header: Text(title(for: group))) {
                ForEach(group, id: \.self){ item in
                    Text("\(item.title!)")
                }
            }
        }

to figure out the title for the group is easy: all items in the group occurred on the same day, so just look at the first item in the group:

private func title(for group: [Item]) -> String {
    String(group[0].timestamp!.formatted(.dateTime.day().month().year()))
}

to do the actual grouping above, you can start with a dicitionary function to group the items by the start of the day of the timestamp. each key will be a start of day time, and each value will be an array of Items whose timestamp has that start of day time. use the result to then combine the dictionary values into an array where the elements are of type [Item]

var groups: [[Item]] {
        let dictionary: [ Date : [Item] ] = Dictionary(grouping: items, by: { Calendar.current.startOfDay(for: $0.timestamp!) })
        var arrayOfArrays = [[Item]]()
        for key in dictionary.keys.sorted() {
            arrayOfArrays.append(dictionary[key]!)
        }
        return arrayOfArrays
}

i think that will do it ... UPDATE: code above has been checked; my original code was certainly aspirational but a little sloppy, but hey, it's Friday (!)

hope that helps,

DMG

2      

Hacking with Swift is sponsored by String Catalog.

SPONSORED Get accurate app localizations in minutes using AI. Choose your languages & receive translations for 40+ markets!

Localize My App

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

Reply to this topic…

You need to create an account or log in to reply.

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.