How to GROUP and SORT fetched core data, and create a List in order?

I have a core data:

entity: Songs

attributes: singer, song


If I want to GROUP & SORT the fetched core data, and make a List---(Section: Singer), (Item: Song), how can I do it?


import SwiftUI

import CoreData


struct SongList: View {

@FetchRequest(entity: Songs.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Songs.song, ascending: true)]) var tutorial: FetchedResults<Tutorial>




func group(_ result : FetchedResults<Songs>)-> [[Songs]] {

return Dictionary(grouping: result) { (element : Songs) in

element.singer!.sorted()

}

.values.map{$0}

}


Using the function, the fetched core data ("singer"), can be grouped and use in the Section of my List. However, the main probem is the order is arbitrary every time, as Dictionary is "unordered". How can I make it in order, if keep using Dictionary? Or, is there any other solution?


The fetched core data ("song"), is in order, in the Item of my List.

As you have mentioned yourself, Dictionary in Swift is an unordered collection.


You cannot sort Dictionary, but you can sort some data retrieved from Dictionary.

For example:

    func group(_ result : FetchedResults<Songs>)-> [[Songs]] {
        
        return Dictionary(grouping: result) { $0.singer!.sorted() }
            .sorted {$0.key.first! < $1.key.first!}
            .map {$0.value}
    }

(You are not showing enough info to write a concrete example. You may need to modify this code to adopt it into your project.)

I tried to apply your function to the Section part of my List:


List {
    
        ForEach((group(songs)), id: \.self) { (section: [Songs]) in
            Text(section[0].singer!)}
        
    }


I got the same result (i.e. Sections go arbitrarily), but I don't know the actual reason. Is there any problem for my codes in the List? I cound't get the result that I want.


I'm very new to Swfit. If you can, please give me some explanation for your codes. 🙂


I'm really grateful for your time and help!

Before requesting something more, you should better show enough info for readers to write a better answer:

- Just a fragment of code does not help, show enough code to reproduce the issue.

- Show complete definition of your Core Data settings, all entities with all attributes and relationships

- Please illustrate what you get with your first code, and with your second (including my `group`)


Without more info, I cannot write explanations.

Got it. Reference to your codes, now the problem's solved. Thank you very much for your time and help!

Thanks for reporting. I am very happy if my replies helped to make your code work.


I believe I could have written a better answer if you had shown us more info.


If you have next chance to post a questions, I recommend you to include enough code to reproduce the issue.

(Unless it takes tens of thousands of lines, a few hundreds is not long.)

func group(_ result : FetchedResults<Songs>)-> [[Songs]] {
        
        return Dictionary(grouping: result) { $0.section! }
            .sorted(by: {$0.key < $1.key})
            .map {$0.value}
        
    }


Based on your codes, I modifed something, and now it works perfectly. Thank you very much!

In SwiftUI, I have a simple core data entity, and one of the attributes called "finished" (Bool).


I fetch the core data to create a List in ListView. When I click an item of the List, it goes to the DetailView, which includes the record "finished".



In the DetailView, I added a toggle button to SHOW the value of "finished", and meanwhile I use this toggle button to UPDATE the record of "finished" in core data.


The curent problem is I can use this toggle button to CHANGE the record in core data; however, the result CANNOT be updated immediately in DeailView. (That means, when I go back to ListView, I see it's updated. And when I click the item and go to DetailView, the record's also properly shown.)


1) How to fix this issue? What's the best way to do it?

2) What's the proper way to assign the core data value of "finished" to the toggle button, when DetailView's launched?



Thanks

Seems your new question is different than the original issue of this thread.

Better start a new thread, including enough code.

Yes, I posted a new quesiton, but don't know why you couldn't see it, so I tried to ask you again here. Any other method can reach you directly?


Please search for this topic: Update SwiftUI View after updating core data value with toggle button


I can change and update the core data record by clicking the button, but the main problem is the updated record (backend) cannot be reflected immediately in the DetailView, after clicking in some case. However, when I go back to ListView, and click to open DetailView again, it's actually there. Any method to refresh the View, to reflect the updated record instantly?


Thanks.

How to GROUP and SORT fetched core data, and create a List in order?
 
 
Q